Commit bc59b558 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'idpf-fix-3-bugs-revealed-by-the-chapter-i'

Tony Nguyen says:

====================
idpf: fix 3 bugs revealed by the Chapter I

Alexander Lobakin says:

The libeth conversion revealed 2 serious issues which lead to sporadic
crashes or WARNs under certain configurations. Additional one was found
while debugging these two with kmemleak.
This one is targeted stable, the rest can be backported manually later
if needed. They can be reproduced only after the conversion is applied
anyway.
====================

Link: https://patch.msgid.link/20240806220923.3359860-1-anthony.l.nguyen@intel.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents da03f5d1 290f1c03
...@@ -900,8 +900,8 @@ static void idpf_vport_stop(struct idpf_vport *vport) ...@@ -900,8 +900,8 @@ static void idpf_vport_stop(struct idpf_vport *vport)
vport->link_up = false; vport->link_up = false;
idpf_vport_intr_deinit(vport); idpf_vport_intr_deinit(vport);
idpf_vport_intr_rel(vport);
idpf_vport_queues_rel(vport); idpf_vport_queues_rel(vport);
idpf_vport_intr_rel(vport);
np->state = __IDPF_VPORT_DOWN; np->state = __IDPF_VPORT_DOWN;
} }
...@@ -1335,9 +1335,8 @@ static void idpf_rx_init_buf_tail(struct idpf_vport *vport) ...@@ -1335,9 +1335,8 @@ static void idpf_rx_init_buf_tail(struct idpf_vport *vport)
/** /**
* idpf_vport_open - Bring up a vport * idpf_vport_open - Bring up a vport
* @vport: vport to bring up * @vport: vport to bring up
* @alloc_res: allocate queue resources
*/ */
static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res) static int idpf_vport_open(struct idpf_vport *vport)
{ {
struct idpf_netdev_priv *np = netdev_priv(vport->netdev); struct idpf_netdev_priv *np = netdev_priv(vport->netdev);
struct idpf_adapter *adapter = vport->adapter; struct idpf_adapter *adapter = vport->adapter;
...@@ -1350,45 +1349,43 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res) ...@@ -1350,45 +1349,43 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res)
/* we do not allow interface up just yet */ /* we do not allow interface up just yet */
netif_carrier_off(vport->netdev); netif_carrier_off(vport->netdev);
if (alloc_res) {
err = idpf_vport_queues_alloc(vport);
if (err)
return err;
}
err = idpf_vport_intr_alloc(vport); err = idpf_vport_intr_alloc(vport);
if (err) { if (err) {
dev_err(&adapter->pdev->dev, "Failed to allocate interrupts for vport %u: %d\n", dev_err(&adapter->pdev->dev, "Failed to allocate interrupts for vport %u: %d\n",
vport->vport_id, err); vport->vport_id, err);
goto queues_rel; return err;
} }
err = idpf_vport_queues_alloc(vport);
if (err)
goto intr_rel;
err = idpf_vport_queue_ids_init(vport); err = idpf_vport_queue_ids_init(vport);
if (err) { if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize queue ids for vport %u: %d\n", dev_err(&adapter->pdev->dev, "Failed to initialize queue ids for vport %u: %d\n",
vport->vport_id, err); vport->vport_id, err);
goto intr_rel; goto queues_rel;
} }
err = idpf_vport_intr_init(vport); err = idpf_vport_intr_init(vport);
if (err) { if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize interrupts for vport %u: %d\n", dev_err(&adapter->pdev->dev, "Failed to initialize interrupts for vport %u: %d\n",
vport->vport_id, err); vport->vport_id, err);
goto intr_rel; goto queues_rel;
} }
err = idpf_rx_bufs_init_all(vport); err = idpf_rx_bufs_init_all(vport);
if (err) { if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize RX buffers for vport %u: %d\n", dev_err(&adapter->pdev->dev, "Failed to initialize RX buffers for vport %u: %d\n",
vport->vport_id, err); vport->vport_id, err);
goto intr_rel; goto queues_rel;
} }
err = idpf_queue_reg_init(vport); err = idpf_queue_reg_init(vport);
if (err) { if (err) {
dev_err(&adapter->pdev->dev, "Failed to initialize queue registers for vport %u: %d\n", dev_err(&adapter->pdev->dev, "Failed to initialize queue registers for vport %u: %d\n",
vport->vport_id, err); vport->vport_id, err);
goto intr_rel; goto queues_rel;
} }
idpf_rx_init_buf_tail(vport); idpf_rx_init_buf_tail(vport);
...@@ -1455,10 +1452,10 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res) ...@@ -1455,10 +1452,10 @@ static int idpf_vport_open(struct idpf_vport *vport, bool alloc_res)
idpf_send_map_unmap_queue_vector_msg(vport, false); idpf_send_map_unmap_queue_vector_msg(vport, false);
intr_deinit: intr_deinit:
idpf_vport_intr_deinit(vport); idpf_vport_intr_deinit(vport);
intr_rel:
idpf_vport_intr_rel(vport);
queues_rel: queues_rel:
idpf_vport_queues_rel(vport); idpf_vport_queues_rel(vport);
intr_rel:
idpf_vport_intr_rel(vport);
return err; return err;
} }
...@@ -1539,7 +1536,7 @@ void idpf_init_task(struct work_struct *work) ...@@ -1539,7 +1536,7 @@ void idpf_init_task(struct work_struct *work)
np = netdev_priv(vport->netdev); np = netdev_priv(vport->netdev);
np->state = __IDPF_VPORT_DOWN; np->state = __IDPF_VPORT_DOWN;
if (test_and_clear_bit(IDPF_VPORT_UP_REQUESTED, vport_config->flags)) if (test_and_clear_bit(IDPF_VPORT_UP_REQUESTED, vport_config->flags))
idpf_vport_open(vport, true); idpf_vport_open(vport);
/* Spawn and return 'idpf_init_task' work queue until all the /* Spawn and return 'idpf_init_task' work queue until all the
* default vports are created * default vports are created
...@@ -1898,9 +1895,6 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport, ...@@ -1898,9 +1895,6 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
goto free_vport; goto free_vport;
} }
err = idpf_vport_queues_alloc(new_vport);
if (err)
goto free_vport;
if (current_state <= __IDPF_VPORT_DOWN) { if (current_state <= __IDPF_VPORT_DOWN) {
idpf_send_delete_queues_msg(vport); idpf_send_delete_queues_msg(vport);
} else { } else {
...@@ -1932,17 +1926,23 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport, ...@@ -1932,17 +1926,23 @@ int idpf_initiate_soft_reset(struct idpf_vport *vport,
err = idpf_set_real_num_queues(vport); err = idpf_set_real_num_queues(vport);
if (err) if (err)
goto err_reset; goto err_open;
if (current_state == __IDPF_VPORT_UP) if (current_state == __IDPF_VPORT_UP)
err = idpf_vport_open(vport, false); err = idpf_vport_open(vport);
kfree(new_vport); kfree(new_vport);
return err; return err;
err_reset: err_reset:
idpf_vport_queues_rel(new_vport); idpf_send_add_queues_msg(vport, vport->num_txq, vport->num_complq,
vport->num_rxq, vport->num_bufq);
err_open:
if (current_state == __IDPF_VPORT_UP)
idpf_vport_open(vport);
free_vport: free_vport:
kfree(new_vport); kfree(new_vport);
...@@ -2171,7 +2171,7 @@ static int idpf_open(struct net_device *netdev) ...@@ -2171,7 +2171,7 @@ static int idpf_open(struct net_device *netdev)
idpf_vport_ctrl_lock(netdev); idpf_vport_ctrl_lock(netdev);
vport = idpf_netdev_to_vport(netdev); vport = idpf_netdev_to_vport(netdev);
err = idpf_vport_open(vport, true); err = idpf_vport_open(vport);
idpf_vport_ctrl_unlock(netdev); idpf_vport_ctrl_unlock(netdev);
......
...@@ -3576,9 +3576,7 @@ static void idpf_vport_intr_napi_dis_all(struct idpf_vport *vport) ...@@ -3576,9 +3576,7 @@ static void idpf_vport_intr_napi_dis_all(struct idpf_vport *vport)
*/ */
void idpf_vport_intr_rel(struct idpf_vport *vport) void idpf_vport_intr_rel(struct idpf_vport *vport)
{ {
int i, j, v_idx; for (u32 v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
for (v_idx = 0; v_idx < vport->num_q_vectors; v_idx++) {
struct idpf_q_vector *q_vector = &vport->q_vectors[v_idx]; struct idpf_q_vector *q_vector = &vport->q_vectors[v_idx];
kfree(q_vector->complq); kfree(q_vector->complq);
...@@ -3593,26 +3591,6 @@ void idpf_vport_intr_rel(struct idpf_vport *vport) ...@@ -3593,26 +3591,6 @@ void idpf_vport_intr_rel(struct idpf_vport *vport)
free_cpumask_var(q_vector->affinity_mask); free_cpumask_var(q_vector->affinity_mask);
} }
/* Clean up the mapping of queues to vectors */
for (i = 0; i < vport->num_rxq_grp; i++) {
struct idpf_rxq_group *rx_qgrp = &vport->rxq_grps[i];
if (idpf_is_queue_model_split(vport->rxq_model))
for (j = 0; j < rx_qgrp->splitq.num_rxq_sets; j++)
rx_qgrp->splitq.rxq_sets[j]->rxq.q_vector = NULL;
else
for (j = 0; j < rx_qgrp->singleq.num_rxq; j++)
rx_qgrp->singleq.rxqs[j]->q_vector = NULL;
}
if (idpf_is_queue_model_split(vport->txq_model))
for (i = 0; i < vport->num_txq_grp; i++)
vport->txq_grps[i].complq->q_vector = NULL;
else
for (i = 0; i < vport->num_txq_grp; i++)
for (j = 0; j < vport->txq_grps[i].num_txq; j++)
vport->txq_grps[i].txqs[j]->q_vector = NULL;
kfree(vport->q_vectors); kfree(vport->q_vectors);
vport->q_vectors = NULL; vport->q_vectors = NULL;
} }
...@@ -3780,13 +3758,15 @@ void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector) ...@@ -3780,13 +3758,15 @@ void idpf_vport_intr_update_itr_ena_irq(struct idpf_q_vector *q_vector)
/** /**
* idpf_vport_intr_req_irq - get MSI-X vectors from the OS for the vport * idpf_vport_intr_req_irq - get MSI-X vectors from the OS for the vport
* @vport: main vport structure * @vport: main vport structure
* @basename: name for the vector
*/ */
static int idpf_vport_intr_req_irq(struct idpf_vport *vport, char *basename) static int idpf_vport_intr_req_irq(struct idpf_vport *vport)
{ {
struct idpf_adapter *adapter = vport->adapter; struct idpf_adapter *adapter = vport->adapter;
const char *drv_name, *if_name, *vec_name;
int vector, err, irq_num, vidx; int vector, err, irq_num, vidx;
const char *vec_name;
drv_name = dev_driver_string(&adapter->pdev->dev);
if_name = netdev_name(vport->netdev);
for (vector = 0; vector < vport->num_q_vectors; vector++) { for (vector = 0; vector < vport->num_q_vectors; vector++) {
struct idpf_q_vector *q_vector = &vport->q_vectors[vector]; struct idpf_q_vector *q_vector = &vport->q_vectors[vector];
...@@ -3804,8 +3784,8 @@ static int idpf_vport_intr_req_irq(struct idpf_vport *vport, char *basename) ...@@ -3804,8 +3784,8 @@ static int idpf_vport_intr_req_irq(struct idpf_vport *vport, char *basename)
else else
continue; continue;
name = kasprintf(GFP_KERNEL, "%s-%s-%d", basename, vec_name, name = kasprintf(GFP_KERNEL, "%s-%s-%s-%d", drv_name, if_name,
vidx); vec_name, vidx);
err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0, err = request_irq(irq_num, idpf_vport_intr_clean_queues, 0,
name, q_vector); name, q_vector);
...@@ -4326,7 +4306,6 @@ int idpf_vport_intr_alloc(struct idpf_vport *vport) ...@@ -4326,7 +4306,6 @@ int idpf_vport_intr_alloc(struct idpf_vport *vport)
*/ */
int idpf_vport_intr_init(struct idpf_vport *vport) int idpf_vport_intr_init(struct idpf_vport *vport)
{ {
char *int_name;
int err; int err;
err = idpf_vport_intr_init_vec_idx(vport); err = idpf_vport_intr_init_vec_idx(vport);
...@@ -4340,11 +4319,7 @@ int idpf_vport_intr_init(struct idpf_vport *vport) ...@@ -4340,11 +4319,7 @@ int idpf_vport_intr_init(struct idpf_vport *vport)
if (err) if (err)
goto unroll_vectors_alloc; goto unroll_vectors_alloc;
int_name = kasprintf(GFP_KERNEL, "%s-%s", err = idpf_vport_intr_req_irq(vport);
dev_driver_string(&vport->adapter->pdev->dev),
vport->netdev->name);
err = idpf_vport_intr_req_irq(vport, int_name);
if (err) if (err)
goto unroll_vectors_alloc; goto unroll_vectors_alloc;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment