Commit 8ee8ee7f authored by Sameeh Jubran's avatar Sameeh Jubran Committed by David S. Miller

net: ena: fix: set freed objects to NULL to avoid failing future allocations

In some cases when a queue related allocation fails, successful past
allocations are freed but the pointer that pointed to them is not
set to NULL. This is a problem for 2 reasons:
1. This is generally a bad practice since this pointer might be
accidentally accessed in the future.
2. Future allocations using the same pointer check if the pointer
is NULL and fail if it is not.

Fixed this by setting such pointers to NULL in the allocation of
queue related objects.

Also refactored the code of ena_setup_tx_resources() to goto-style
error handling to avoid code duplication of resource freeing.

Fixes: 1738cd3e ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)")
Signed-off-by: default avatarArthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: default avatarSameeh Jubran <sameehj@amazon.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3c6eeff2
...@@ -224,28 +224,23 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid) ...@@ -224,28 +224,23 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
if (!tx_ring->tx_buffer_info) { if (!tx_ring->tx_buffer_info) {
tx_ring->tx_buffer_info = vzalloc(size); tx_ring->tx_buffer_info = vzalloc(size);
if (!tx_ring->tx_buffer_info) if (!tx_ring->tx_buffer_info)
return -ENOMEM; goto err_tx_buffer_info;
} }
size = sizeof(u16) * tx_ring->ring_size; size = sizeof(u16) * tx_ring->ring_size;
tx_ring->free_tx_ids = vzalloc_node(size, node); tx_ring->free_tx_ids = vzalloc_node(size, node);
if (!tx_ring->free_tx_ids) { if (!tx_ring->free_tx_ids) {
tx_ring->free_tx_ids = vzalloc(size); tx_ring->free_tx_ids = vzalloc(size);
if (!tx_ring->free_tx_ids) { if (!tx_ring->free_tx_ids)
vfree(tx_ring->tx_buffer_info); goto err_free_tx_ids;
return -ENOMEM;
}
} }
size = tx_ring->tx_max_header_size; size = tx_ring->tx_max_header_size;
tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node); tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node);
if (!tx_ring->push_buf_intermediate_buf) { if (!tx_ring->push_buf_intermediate_buf) {
tx_ring->push_buf_intermediate_buf = vzalloc(size); tx_ring->push_buf_intermediate_buf = vzalloc(size);
if (!tx_ring->push_buf_intermediate_buf) { if (!tx_ring->push_buf_intermediate_buf)
vfree(tx_ring->tx_buffer_info); goto err_push_buf_intermediate_buf;
vfree(tx_ring->free_tx_ids);
return -ENOMEM;
}
} }
/* Req id ring for TX out of order completions */ /* Req id ring for TX out of order completions */
...@@ -259,6 +254,15 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid) ...@@ -259,6 +254,15 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid)
tx_ring->next_to_clean = 0; tx_ring->next_to_clean = 0;
tx_ring->cpu = ena_irq->cpu; tx_ring->cpu = ena_irq->cpu;
return 0; return 0;
err_push_buf_intermediate_buf:
vfree(tx_ring->free_tx_ids);
tx_ring->free_tx_ids = NULL;
err_free_tx_ids:
vfree(tx_ring->tx_buffer_info);
tx_ring->tx_buffer_info = NULL;
err_tx_buffer_info:
return -ENOMEM;
} }
/* ena_free_tx_resources - Free I/O Tx Resources per Queue /* ena_free_tx_resources - Free I/O Tx Resources per Queue
...@@ -378,6 +382,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter, ...@@ -378,6 +382,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter,
rx_ring->free_rx_ids = vzalloc(size); rx_ring->free_rx_ids = vzalloc(size);
if (!rx_ring->free_rx_ids) { if (!rx_ring->free_rx_ids) {
vfree(rx_ring->rx_buffer_info); vfree(rx_ring->rx_buffer_info);
rx_ring->rx_buffer_info = NULL;
return -ENOMEM; return -ENOMEM;
} }
} }
......
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