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

Commit 2dd689c8 authored by Shivasharan S's avatar Shivasharan S Committed by Martin K. Petersen
Browse files

scsi: megaraid_sas: reduce size of fusion_context and use kmalloc for allocation

fusion_context structure is very large around 180kB and most of the size
is contributed by log_to_span array. Move log_to_span out of fusion
context and have separate allocation for log_to_span. And use kmalloc to
allocate fusion_context.  Currently kmemleak reports 1000s of false
positives for fusion->cmd_list[]. kmemleak does not track page
allocation for fusion_context. This change will also fix the false
positives reported by kmemleak.

Ref: https://marc.info/?l=linux-scsi&m=150545293900917



Reported-by: default avatarShu Wang <shuwang@redhat.com>
Signed-off-by: default avatarKashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: default avatarShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent f369a315
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -2218,7 +2218,6 @@ struct megasas_instance {

	/* Ptr to hba specific information */
	void *ctrl_context;
	u32 ctrl_context_pages;
	struct megasas_ctrl_info *ctrl_info;
	unsigned int msix_vectors;
	struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
+29 −14
Original line number Diff line number Diff line
@@ -4502,20 +4502,31 @@ megasas_alloc_fusion_context(struct megasas_instance *instance)
{
	struct fusion_context *fusion;

	instance->ctrl_context_pages = get_order(sizeof(struct fusion_context));
	instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
		instance->ctrl_context_pages);
	if (!instance->ctrl_context) {
		/* fall back to using vmalloc for fusion_context */
		instance->ctrl_context = vzalloc(sizeof(struct fusion_context));
	instance->ctrl_context = kzalloc(sizeof(struct fusion_context),
					 GFP_KERNEL);
	if (!instance->ctrl_context) {
			dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__);
		dev_err(&instance->pdev->dev, "Failed from %s %d\n",
			__func__, __LINE__);
		return -ENOMEM;
	}
	}

	fusion = instance->ctrl_context;

	fusion->log_to_span_pages = get_order(MAX_LOGICAL_DRIVES_EXT *
					      sizeof(LD_SPAN_INFO));
	fusion->log_to_span =
		(PLD_SPAN_INFO)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
						fusion->log_to_span_pages);
	if (!fusion->log_to_span) {
		fusion->log_to_span = vzalloc(MAX_LOGICAL_DRIVES_EXT *
					      sizeof(LD_SPAN_INFO));
		if (!fusion->log_to_span) {
			dev_err(&instance->pdev->dev, "Failed from %s %d\n",
				__func__, __LINE__);
			return -ENOMEM;
		}
	}

	fusion->load_balance_info_pages = get_order(MAX_LOGICAL_DRIVES_EXT *
		sizeof(struct LD_LOAD_BALANCE_INFO));
	fusion->load_balance_info =
@@ -4546,11 +4557,15 @@ megasas_free_fusion_context(struct megasas_instance *instance)
					fusion->load_balance_info_pages);
		}

		if (is_vmalloc_addr(fusion))
			vfree(fusion);
		if (fusion->log_to_span) {
			if (is_vmalloc_addr(fusion->log_to_span))
				vfree(fusion->log_to_span);
			else
			free_pages((ulong)fusion,
				instance->ctrl_context_pages);
				free_pages((ulong)fusion->log_to_span,
					   fusion->log_to_span_pages);
		}

		kfree(fusion);
	}
}

+2 −1
Original line number Diff line number Diff line
@@ -1312,7 +1312,8 @@ struct fusion_context {
	u8 fast_path_io;
	struct LD_LOAD_BALANCE_INFO *load_balance_info;
	u32 load_balance_info_pages;
	LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
	LD_SPAN_INFO *log_to_span;
	u32 log_to_span_pages;
	struct LD_STREAM_DETECT **stream_detect_by_ld;
};