Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fdbcbcab authored by Maurizio Lombardi's avatar Maurizio Lombardi Committed by Christoph Hellwig
Browse files

bnx2fc: fix memory leak in bnx2fc_allocate_hash_table()



In case of error, the bnx2fc_allocate_hash_table() didn't free
all the memory it allocated.

Signed-off-by: default avatarMaurizio Lombardi <mlombard@redhat.com>
Acked-by: default avatarEddie Wai <eddie.wai@broadcom.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent 91d9f809
Loading
Loading
Loading
Loading
+19 −12
Original line number Original line Diff line number Diff line
@@ -2026,7 +2026,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
	dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL);
	dma_segment_array = kzalloc(dma_segment_array_size, GFP_KERNEL);
	if (!dma_segment_array) {
	if (!dma_segment_array) {
		printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n");
		printk(KERN_ERR PFX "hash table pointers (dma) alloc failed\n");
		return -ENOMEM;
		goto cleanup_ht;
	}
	}


	for (i = 0; i < segment_count; ++i) {
	for (i = 0; i < segment_count; ++i) {
@@ -2037,15 +2037,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
					   GFP_KERNEL);
					   GFP_KERNEL);
		if (!hba->hash_tbl_segments[i]) {
		if (!hba->hash_tbl_segments[i]) {
			printk(KERN_ERR PFX "hash segment alloc failed\n");
			printk(KERN_ERR PFX "hash segment alloc failed\n");
			while (--i >= 0) {
			goto cleanup_dma;
				dma_free_coherent(&hba->pcidev->dev,
						    BNX2FC_HASH_TBL_CHUNK_SIZE,
						    hba->hash_tbl_segments[i],
						    dma_segment_array[i]);
				hba->hash_tbl_segments[i] = NULL;
			}
			kfree(dma_segment_array);
			return -ENOMEM;
		}
		}
		memset(hba->hash_tbl_segments[i], 0,
		memset(hba->hash_tbl_segments[i], 0,
		       BNX2FC_HASH_TBL_CHUNK_SIZE);
		       BNX2FC_HASH_TBL_CHUNK_SIZE);
@@ -2057,8 +2049,7 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
					       GFP_KERNEL);
					       GFP_KERNEL);
	if (!hba->hash_tbl_pbl) {
	if (!hba->hash_tbl_pbl) {
		printk(KERN_ERR PFX "hash table pbl alloc failed\n");
		printk(KERN_ERR PFX "hash table pbl alloc failed\n");
		kfree(dma_segment_array);
		goto cleanup_dma;
		return -ENOMEM;
	}
	}
	memset(hba->hash_tbl_pbl, 0, PAGE_SIZE);
	memset(hba->hash_tbl_pbl, 0, PAGE_SIZE);


@@ -2083,6 +2074,22 @@ static int bnx2fc_allocate_hash_table(struct bnx2fc_hba *hba)
	}
	}
	kfree(dma_segment_array);
	kfree(dma_segment_array);
	return 0;
	return 0;

cleanup_dma:
	for (i = 0; i < segment_count; ++i) {
		if (hba->hash_tbl_segments[i])
			dma_free_coherent(&hba->pcidev->dev,
					    BNX2FC_HASH_TBL_CHUNK_SIZE,
					    hba->hash_tbl_segments[i],
					    dma_segment_array[i]);
	}

	kfree(dma_segment_array);

cleanup_ht:
	kfree(hba->hash_tbl_segments);
	hba->hash_tbl_segments = NULL;
	return -ENOMEM;
}
}


/**
/**