forked from luck/tmp_suning_uos_patched
ionic: change queue count with no reset
Add to our new ionic_reconfigure_queues() to also be able to change the number of queues in use, and to change the queue interrupt layout between split and combined. Signed-off-by: Shannon Nelson <snelson@pensando.io> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a34e25ab97
commit
101b40a017
|
@ -561,32 +561,15 @@ static void ionic_get_channels(struct net_device *netdev,
|
|||
}
|
||||
}
|
||||
|
||||
static void ionic_set_queuecount(struct ionic_lif *lif, void *arg)
|
||||
{
|
||||
struct ethtool_channels *ch = arg;
|
||||
|
||||
if (ch->combined_count) {
|
||||
lif->nxqs = ch->combined_count;
|
||||
if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
|
||||
clear_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
|
||||
lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
|
||||
lif->tx_coalesce_hw = lif->rx_coalesce_hw;
|
||||
netdev_info(lif->netdev, "Sharing queue interrupts\n");
|
||||
}
|
||||
} else {
|
||||
lif->nxqs = ch->rx_count;
|
||||
if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state)) {
|
||||
set_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
|
||||
netdev_info(lif->netdev, "Splitting queue interrupts\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ionic_set_channels(struct net_device *netdev,
|
||||
struct ethtool_channels *ch)
|
||||
{
|
||||
struct ionic_lif *lif = netdev_priv(netdev);
|
||||
int new_cnt;
|
||||
struct ionic_queue_params qparam;
|
||||
int max_cnt;
|
||||
int err;
|
||||
|
||||
ionic_init_queue_params(lif, &qparam);
|
||||
|
||||
if (ch->rx_count != ch->tx_count) {
|
||||
netdev_info(netdev, "The rx and tx count must be equal\n");
|
||||
|
@ -594,20 +577,63 @@ static int ionic_set_channels(struct net_device *netdev,
|
|||
}
|
||||
|
||||
if (ch->combined_count && ch->rx_count) {
|
||||
netdev_info(netdev, "Use either combined_count or rx/tx_count, not both\n");
|
||||
netdev_info(netdev, "Use either combined or rx and tx, not both\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ch->combined_count)
|
||||
new_cnt = ch->combined_count;
|
||||
else
|
||||
new_cnt = ch->rx_count;
|
||||
max_cnt = lif->ionic->ntxqs_per_lif;
|
||||
if (ch->combined_count) {
|
||||
if (ch->combined_count > max_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
if (lif->nxqs != new_cnt)
|
||||
netdev_info(netdev, "Changing queue count from %d to %d\n",
|
||||
lif->nxqs, new_cnt);
|
||||
if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
|
||||
netdev_info(lif->netdev, "Sharing queue interrupts\n");
|
||||
else if (ch->combined_count == lif->nxqs)
|
||||
return 0;
|
||||
|
||||
return ionic_reset_queues(lif, ionic_set_queuecount, ch);
|
||||
if (lif->nxqs != ch->combined_count)
|
||||
netdev_info(netdev, "Changing queue count from %d to %d\n",
|
||||
lif->nxqs, ch->combined_count);
|
||||
|
||||
qparam.nxqs = ch->combined_count;
|
||||
qparam.intr_split = 0;
|
||||
} else {
|
||||
max_cnt /= 2;
|
||||
if (ch->rx_count > max_cnt)
|
||||
return -EINVAL;
|
||||
|
||||
if (!test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
|
||||
netdev_info(lif->netdev, "Splitting queue interrupts\n");
|
||||
else if (ch->rx_count == lif->nxqs)
|
||||
return 0;
|
||||
|
||||
if (lif->nxqs != ch->rx_count)
|
||||
netdev_info(netdev, "Changing queue count from %d to %d\n",
|
||||
lif->nxqs, ch->rx_count);
|
||||
|
||||
qparam.nxqs = ch->rx_count;
|
||||
qparam.intr_split = 1;
|
||||
}
|
||||
|
||||
/* if we're not running, just set the values and return */
|
||||
if (!netif_running(lif->netdev)) {
|
||||
lif->nxqs = qparam.nxqs;
|
||||
|
||||
if (qparam.intr_split) {
|
||||
set_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
|
||||
} else {
|
||||
clear_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
|
||||
lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
|
||||
lif->tx_coalesce_hw = lif->rx_coalesce_hw;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = ionic_reconfigure_queues(lif, &qparam);
|
||||
if (err)
|
||||
netdev_info(netdev, "Queue reconfiguration failed, changes canceled: %d\n", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static u32 ionic_get_priv_flags(struct net_device *netdev)
|
||||
|
|
|
@ -299,6 +299,18 @@ static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
|||
qcq->flags &= ~IONIC_QCQ_F_INITED;
|
||||
}
|
||||
|
||||
static void ionic_qcq_intr_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
||||
{
|
||||
if (!(qcq->flags & IONIC_QCQ_F_INTR) || qcq->intr.vector == 0)
|
||||
return;
|
||||
|
||||
irq_set_affinity_hint(qcq->intr.vector, NULL);
|
||||
devm_free_irq(lif->ionic->dev, qcq->intr.vector, &qcq->napi);
|
||||
qcq->intr.vector = 0;
|
||||
ionic_intr_free(lif->ionic, qcq->intr.index);
|
||||
qcq->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
|
||||
}
|
||||
|
||||
static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
||||
{
|
||||
struct device *dev = lif->ionic->dev;
|
||||
|
@ -326,12 +338,7 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
|||
qcq->sg_base_pa = 0;
|
||||
}
|
||||
|
||||
if (qcq->flags & IONIC_QCQ_F_INTR) {
|
||||
irq_set_affinity_hint(qcq->intr.vector, NULL);
|
||||
devm_free_irq(dev, qcq->intr.vector, &qcq->napi);
|
||||
qcq->intr.vector = 0;
|
||||
ionic_intr_free(lif->ionic, qcq->intr.index);
|
||||
}
|
||||
ionic_qcq_intr_free(lif, qcq);
|
||||
|
||||
if (qcq->cq.info) {
|
||||
devm_kfree(dev, qcq->cq.info);
|
||||
|
@ -341,7 +348,6 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
|||
devm_kfree(dev, qcq->q.info);
|
||||
qcq->q.info = NULL;
|
||||
}
|
||||
devm_kfree(dev, qcq);
|
||||
}
|
||||
|
||||
static void ionic_qcqs_free(struct ionic_lif *lif)
|
||||
|
@ -350,11 +356,13 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
|
|||
|
||||
if (lif->notifyqcq) {
|
||||
ionic_qcq_free(lif, lif->notifyqcq);
|
||||
devm_kfree(dev, lif->notifyqcq);
|
||||
lif->notifyqcq = NULL;
|
||||
}
|
||||
|
||||
if (lif->adminqcq) {
|
||||
ionic_qcq_free(lif, lif->adminqcq);
|
||||
devm_kfree(dev, lif->adminqcq);
|
||||
lif->adminqcq = NULL;
|
||||
}
|
||||
|
||||
|
@ -385,6 +393,53 @@ static void ionic_link_qcq_interrupts(struct ionic_qcq *src_qcq,
|
|||
n_qcq->intr.index = src_qcq->intr.index;
|
||||
}
|
||||
|
||||
static int ionic_alloc_qcq_interrupt(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!(qcq->flags & IONIC_QCQ_F_INTR)) {
|
||||
qcq->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
err = ionic_intr_alloc(lif, &qcq->intr);
|
||||
if (err) {
|
||||
netdev_warn(lif->netdev, "no intr for %s: %d\n",
|
||||
qcq->q.name, err);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err = ionic_bus_get_irq(lif->ionic, qcq->intr.index);
|
||||
if (err < 0) {
|
||||
netdev_warn(lif->netdev, "no vector for %s: %d\n",
|
||||
qcq->q.name, err);
|
||||
goto err_out_free_intr;
|
||||
}
|
||||
qcq->intr.vector = err;
|
||||
ionic_intr_mask_assert(lif->ionic->idev.intr_ctrl, qcq->intr.index,
|
||||
IONIC_INTR_MASK_SET);
|
||||
|
||||
err = ionic_request_irq(lif, qcq);
|
||||
if (err) {
|
||||
netdev_warn(lif->netdev, "irq request failed %d\n", err);
|
||||
goto err_out_free_intr;
|
||||
}
|
||||
|
||||
/* try to get the irq on the local numa node first */
|
||||
qcq->intr.cpu = cpumask_local_spread(qcq->intr.index,
|
||||
dev_to_node(lif->ionic->dev));
|
||||
if (qcq->intr.cpu != -1)
|
||||
cpumask_set_cpu(qcq->intr.cpu, &qcq->intr.affinity_mask);
|
||||
|
||||
netdev_dbg(lif->netdev, "%s: Interrupt index %d\n", qcq->q.name, qcq->intr.index);
|
||||
return 0;
|
||||
|
||||
err_out_free_intr:
|
||||
ionic_intr_free(lif->ionic, qcq->intr.index);
|
||||
err_out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
|
||||
unsigned int index,
|
||||
const char *name, unsigned int flags,
|
||||
|
@ -430,39 +485,9 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
|
|||
goto err_out_free_q_info;
|
||||
}
|
||||
|
||||
if (flags & IONIC_QCQ_F_INTR) {
|
||||
err = ionic_intr_alloc(lif, &new->intr);
|
||||
if (err) {
|
||||
netdev_warn(lif->netdev, "no intr for %s: %d\n",
|
||||
new->q.name, err);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
err = ionic_bus_get_irq(lif->ionic, new->intr.index);
|
||||
if (err < 0) {
|
||||
netdev_warn(lif->netdev, "no vector for %s: %d\n",
|
||||
new->q.name, err);
|
||||
goto err_out_free_intr;
|
||||
}
|
||||
new->intr.vector = err;
|
||||
ionic_intr_mask_assert(idev->intr_ctrl, new->intr.index,
|
||||
IONIC_INTR_MASK_SET);
|
||||
|
||||
err = ionic_request_irq(lif, new);
|
||||
if (err) {
|
||||
netdev_warn(lif->netdev, "irq request failed for %s: %d\n",
|
||||
new->q.name, err);
|
||||
goto err_out_free_intr;
|
||||
}
|
||||
|
||||
new->intr.cpu = cpumask_local_spread(new->intr.index,
|
||||
dev_to_node(dev));
|
||||
if (new->intr.cpu != -1)
|
||||
cpumask_set_cpu(new->intr.cpu,
|
||||
&new->intr.affinity_mask);
|
||||
} else {
|
||||
new->intr.index = IONIC_INTR_INDEX_NOT_ASSIGNED;
|
||||
}
|
||||
err = ionic_alloc_qcq_interrupt(lif, new);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
new->cq.info = devm_kcalloc(dev, num_descs, sizeof(*new->cq.info),
|
||||
GFP_KERNEL);
|
||||
|
@ -528,11 +553,10 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
|
|||
err_out_free_cq_info:
|
||||
devm_kfree(dev, new->cq.info);
|
||||
err_out_free_irq:
|
||||
if (flags & IONIC_QCQ_F_INTR)
|
||||
if (flags & IONIC_QCQ_F_INTR) {
|
||||
devm_free_irq(dev, new->intr.vector, &new->napi);
|
||||
err_out_free_intr:
|
||||
if (flags & IONIC_QCQ_F_INTR)
|
||||
ionic_intr_free(lif->ionic, new->intr.index);
|
||||
}
|
||||
err_out_free_q_info:
|
||||
devm_kfree(dev, new->q.info);
|
||||
err_out_free_qcq:
|
||||
|
@ -635,7 +659,7 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
|||
unsigned int intr_index;
|
||||
int err;
|
||||
|
||||
if (test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state))
|
||||
if (qcq->flags & IONIC_QCQ_F_INTR)
|
||||
intr_index = qcq->intr.index;
|
||||
else
|
||||
intr_index = lif->rxqcqs[q->index]->intr.index;
|
||||
|
@ -1539,7 +1563,7 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
|
|||
unsigned int i;
|
||||
|
||||
if (lif->txqcqs) {
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < lif->nxqs && lif->txqcqs[i]; i++) {
|
||||
ionic_lif_qcq_deinit(lif, lif->txqcqs[i]);
|
||||
ionic_tx_flush(&lif->txqcqs[i]->cq);
|
||||
ionic_tx_empty(&lif->txqcqs[i]->q);
|
||||
|
@ -1547,7 +1571,7 @@ static void ionic_txrx_deinit(struct ionic_lif *lif)
|
|||
}
|
||||
|
||||
if (lif->rxqcqs) {
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < lif->nxqs && lif->rxqcqs[i]; i++) {
|
||||
ionic_lif_qcq_deinit(lif, lif->rxqcqs[i]);
|
||||
ionic_rx_flush(&lif->rxqcqs[i]->cq);
|
||||
ionic_rx_empty(&lif->rxqcqs[i]->q);
|
||||
|
@ -1561,15 +1585,17 @@ static void ionic_txrx_free(struct ionic_lif *lif)
|
|||
unsigned int i;
|
||||
|
||||
if (lif->txqcqs) {
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < lif->ionic->ntxqs_per_lif && lif->txqcqs[i]; i++) {
|
||||
ionic_qcq_free(lif, lif->txqcqs[i]);
|
||||
devm_kfree(lif->ionic->dev, lif->txqcqs[i]);
|
||||
lif->txqcqs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (lif->rxqcqs) {
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < lif->ionic->nrxqs_per_lif && lif->rxqcqs[i]; i++) {
|
||||
ionic_qcq_free(lif, lif->rxqcqs[i]);
|
||||
devm_kfree(lif->ionic->dev, lif->rxqcqs[i]);
|
||||
lif->rxqcqs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2088,20 +2114,22 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
|
|||
unsigned int i;
|
||||
|
||||
/* allocate temporary qcq arrays to hold new queue structs */
|
||||
if (qparam->ntxq_descs != lif->ntxq_descs) {
|
||||
tx_qcqs = devm_kcalloc(lif->ionic->dev, lif->nxqs,
|
||||
if (qparam->nxqs != lif->nxqs || qparam->ntxq_descs != lif->ntxq_descs) {
|
||||
tx_qcqs = devm_kcalloc(lif->ionic->dev, lif->ionic->ntxqs_per_lif,
|
||||
sizeof(struct ionic_qcq *), GFP_KERNEL);
|
||||
if (!tx_qcqs)
|
||||
goto err_out;
|
||||
}
|
||||
if (qparam->nrxq_descs != lif->nrxq_descs) {
|
||||
rx_qcqs = devm_kcalloc(lif->ionic->dev, lif->nxqs,
|
||||
if (qparam->nxqs != lif->nxqs || qparam->nrxq_descs != lif->nrxq_descs) {
|
||||
rx_qcqs = devm_kcalloc(lif->ionic->dev, lif->ionic->nrxqs_per_lif,
|
||||
sizeof(struct ionic_qcq *), GFP_KERNEL);
|
||||
if (!rx_qcqs)
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* allocate new desc_info and rings with no interrupt flag */
|
||||
/* allocate new desc_info and rings, but leave the interrupt setup
|
||||
* until later so as to not mess with the still-running queues
|
||||
*/
|
||||
if (lif->qtype_info[IONIC_QTYPE_TXQ].version >= 1 &&
|
||||
lif->qtype_info[IONIC_QTYPE_TXQ].sg_desc_sz ==
|
||||
sizeof(struct ionic_txq_sg_desc_v1))
|
||||
|
@ -2110,7 +2138,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
|
|||
sg_desc_sz = sizeof(struct ionic_txq_sg_desc);
|
||||
|
||||
if (tx_qcqs) {
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < qparam->nxqs; i++) {
|
||||
flags = lif->txqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
|
||||
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
|
||||
qparam->ntxq_descs,
|
||||
|
@ -2124,7 +2152,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
|
|||
}
|
||||
|
||||
if (rx_qcqs) {
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < qparam->nxqs; i++) {
|
||||
flags = lif->rxqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
|
||||
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
|
||||
qparam->nrxq_descs,
|
||||
|
@ -2140,33 +2168,90 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
|
|||
/* stop and clean the queues */
|
||||
ionic_stop_queues_reconfig(lif);
|
||||
|
||||
if (qparam->nxqs != lif->nxqs) {
|
||||
err = netif_set_real_num_tx_queues(lif->netdev, qparam->nxqs);
|
||||
if (err)
|
||||
goto err_out_reinit_unlock;
|
||||
err = netif_set_real_num_rx_queues(lif->netdev, qparam->nxqs);
|
||||
if (err) {
|
||||
netif_set_real_num_tx_queues(lif->netdev, lif->nxqs);
|
||||
goto err_out_reinit_unlock;
|
||||
}
|
||||
}
|
||||
|
||||
/* swap new desc_info and rings, keeping existing interrupt config */
|
||||
if (tx_qcqs) {
|
||||
lif->ntxq_descs = qparam->ntxq_descs;
|
||||
for (i = 0; i < lif->nxqs; i++)
|
||||
for (i = 0; i < qparam->nxqs; i++)
|
||||
ionic_swap_queues(lif->txqcqs[i], tx_qcqs[i]);
|
||||
}
|
||||
|
||||
if (rx_qcqs) {
|
||||
lif->nrxq_descs = qparam->nrxq_descs;
|
||||
for (i = 0; i < lif->nxqs; i++)
|
||||
for (i = 0; i < qparam->nxqs; i++)
|
||||
ionic_swap_queues(lif->rxqcqs[i], rx_qcqs[i]);
|
||||
}
|
||||
|
||||
/* re-init the queues */
|
||||
err = ionic_start_queues_reconfig(lif);
|
||||
/* if we need to change the interrupt layout, this is the time */
|
||||
if (qparam->intr_split != test_bit(IONIC_LIF_F_SPLIT_INTR, lif->state) ||
|
||||
qparam->nxqs != lif->nxqs) {
|
||||
if (qparam->intr_split) {
|
||||
set_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
|
||||
} else {
|
||||
clear_bit(IONIC_LIF_F_SPLIT_INTR, lif->state);
|
||||
lif->tx_coalesce_usecs = lif->rx_coalesce_usecs;
|
||||
lif->tx_coalesce_hw = lif->rx_coalesce_hw;
|
||||
}
|
||||
|
||||
/* clear existing interrupt assignments */
|
||||
for (i = 0; i < lif->ionic->ntxqs_per_lif; i++) {
|
||||
ionic_qcq_intr_free(lif, lif->txqcqs[i]);
|
||||
ionic_qcq_intr_free(lif, lif->rxqcqs[i]);
|
||||
}
|
||||
|
||||
/* re-assign the interrupts */
|
||||
for (i = 0; i < qparam->nxqs; i++) {
|
||||
lif->rxqcqs[i]->flags |= IONIC_QCQ_F_INTR;
|
||||
err = ionic_alloc_qcq_interrupt(lif, lif->rxqcqs[i]);
|
||||
ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
|
||||
lif->rxqcqs[i]->intr.index,
|
||||
lif->rx_coalesce_hw);
|
||||
|
||||
if (qparam->intr_split) {
|
||||
lif->txqcqs[i]->flags |= IONIC_QCQ_F_INTR;
|
||||
err = ionic_alloc_qcq_interrupt(lif, lif->txqcqs[i]);
|
||||
ionic_intr_coal_init(lif->ionic->idev.intr_ctrl,
|
||||
lif->txqcqs[i]->intr.index,
|
||||
lif->tx_coalesce_hw);
|
||||
} else {
|
||||
lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_link_qcq_interrupts(lif->rxqcqs[i], lif->txqcqs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swap(lif->nxqs, qparam->nxqs);
|
||||
|
||||
err_out_reinit_unlock:
|
||||
/* re-init the queues, but don't loose an error code */
|
||||
if (err)
|
||||
ionic_start_queues_reconfig(lif);
|
||||
else
|
||||
err = ionic_start_queues_reconfig(lif);
|
||||
|
||||
err_out:
|
||||
/* free old allocs without cleaning intr */
|
||||
for (i = 0; i < lif->nxqs; i++) {
|
||||
for (i = 0; i < qparam->nxqs; i++) {
|
||||
if (tx_qcqs && tx_qcqs[i]) {
|
||||
tx_qcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, tx_qcqs[i]);
|
||||
devm_kfree(lif->ionic->dev, tx_qcqs[i]);
|
||||
tx_qcqs[i] = NULL;
|
||||
}
|
||||
if (rx_qcqs && rx_qcqs[i]) {
|
||||
rx_qcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, rx_qcqs[i]);
|
||||
devm_kfree(lif->ionic->dev, rx_qcqs[i]);
|
||||
rx_qcqs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -2181,6 +2266,17 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
|
|||
tx_qcqs = NULL;
|
||||
}
|
||||
|
||||
/* clean the unused dma and info allocations when new set is smaller
|
||||
* than the full array, but leave the qcq shells in place
|
||||
*/
|
||||
for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) {
|
||||
lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, lif->txqcqs[i]);
|
||||
|
||||
lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, lif->rxqcqs[i]);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user