Skip to content

Commit

Permalink
cxgb4: fix the error path of cxgb4_uld_register()
Browse files Browse the repository at this point in the history
On multi adapter setup if the uld registration fails even on
one adapter, the allocated resources for the uld on all the
adapters are freed, rendering the functioning adapters unusable.

This commit fixes the issue by freeing the allocated resources
only for the failed adapter.

Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Ganesh Goudar authored and David S. Miller committed Oct 18, 2018
1 parent 35b842f commit 40b0655
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 39 deletions.
4 changes: 1 addition & 3 deletions drivers/crypto/chelsio/chcr_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,7 @@ static int chcr_uld_state_change(void *handle, enum cxgb4_state state)

static int __init chcr_crypto_init(void)
{
if (cxgb4_register_uld(CXGB4_ULD_CRYPTO, &chcr_uld_info))
pr_err("ULD register fail: No chcr crypto support in cxgb4\n");

cxgb4_register_uld(CXGB4_ULD_CRYPTO, &chcr_uld_info);
return 0;
}

Expand Down
46 changes: 11 additions & 35 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,15 +702,14 @@ static void uld_attach(struct adapter *adap, unsigned int uld)
* about any presently available devices that support its type. Returns
* %-EBUSY if a ULD of the same type is already registered.
*/
int cxgb4_register_uld(enum cxgb4_uld type,
const struct cxgb4_uld_info *p)
void cxgb4_register_uld(enum cxgb4_uld type,
const struct cxgb4_uld_info *p)
{
int ret = 0;
unsigned int adap_idx = 0;
struct adapter *adap;

if (type >= CXGB4_ULD_MAX)
return -EINVAL;
return;

mutex_lock(&uld_mutex);
list_for_each_entry(adap, &adapter_list, list_node) {
Expand All @@ -733,52 +732,29 @@ int cxgb4_register_uld(enum cxgb4_uld type,
}
if (adap->flags & FULL_INIT_DONE)
enable_rx_uld(adap, type);
if (adap->uld[type].add) {
ret = -EBUSY;
if (adap->uld[type].add)
goto free_irq;
}
ret = setup_sge_txq_uld(adap, type, p);
if (ret)
goto free_irq;
adap->uld[type] = *p;
uld_attach(adap, type);
adap_idx++;
}
mutex_unlock(&uld_mutex);
return 0;

continue;
free_irq:
if (adap->flags & FULL_INIT_DONE)
quiesce_rx_uld(adap, type);
if (adap->flags & USING_MSIX)
free_msix_queue_irqs_uld(adap, type);
free_rxq:
free_sge_queues_uld(adap, type);
free_queues:
free_queues_uld(adap, type);
out:

list_for_each_entry(adap, &adapter_list, list_node) {
if ((type == CXGB4_ULD_CRYPTO && !is_pci_uld(adap)) ||
(type != CXGB4_ULD_CRYPTO && !is_offload(adap)))
continue;
if (type == CXGB4_ULD_ISCSIT && is_t4(adap->params.chip))
continue;
if (!adap_idx)
break;
adap->uld[type].handle = NULL;
adap->uld[type].add = NULL;
release_sge_txq_uld(adap, type);
if (adap->flags & FULL_INIT_DONE)
quiesce_rx_uld(adap, type);
if (adap->flags & USING_MSIX)
free_msix_queue_irqs_uld(adap, type);
free_rxq:
free_sge_queues_uld(adap, type);
free_queues:
free_queues_uld(adap, type);
adap_idx--;
out:
dev_warn(adap->pdev_dev,
"ULD registration failed for uld type %d\n", type);
}
mutex_unlock(&uld_mutex);
return ret;
return;
}
EXPORT_SYMBOL(cxgb4_register_uld);

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/chelsio/cxgb4/cxgb4_uld.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ struct cxgb4_uld_info {
int (*tx_handler)(struct sk_buff *skb, struct net_device *dev);
};

int cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
void cxgb4_register_uld(enum cxgb4_uld type, const struct cxgb4_uld_info *p);
int cxgb4_unregister_uld(enum cxgb4_uld type);
int cxgb4_ofld_send(struct net_device *dev, struct sk_buff *skb);
int cxgb4_immdata_send(struct net_device *dev, unsigned int idx,
Expand Down

0 comments on commit 40b0655

Please sign in to comment.