From: Sumit Saxena Date: Thu, 1 Mar 2018 11:18:16 +0000 (-0500) Subject: scsi: megaraid_sas: reduce size of fusion_context and use kmalloc for allocation X-Git-Tag: v4.1.12-124.31.3~1048 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=9a7a01dd90e105eb1ddaa8a4af12b4f230d2cd14;p=users%2Fjedix%2Flinux-maple.git 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 Rebased for UEK kernel. Reported-by: Shu Wang Signed-off-by: Kashyap Desai Signed-off-by: Shivasharan S Signed-off-by: Martin K. Petersen Signed-off-by: Sumit Saxena Orabug: 27625001 Signed-off-by: Jack Vogel Reviewed-by: Martin K. Petersen --- diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index e2e9ea06ddae5..e2817a4364569 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -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 msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES]; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 30db0ae7053eb..f5d3df2cf7d22 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -4503,20 +4503,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); + instance->ctrl_context = kzalloc(sizeof(struct fusion_context), + GFP_KERNEL); if (!instance->ctrl_context) { - /* fall back to using vmalloc for fusion_context */ - instance->ctrl_context = vzalloc(sizeof(struct fusion_context)); - if (!instance->ctrl_context) { - dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__); - return -ENOMEM; - } + 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 = @@ -4547,11 +4558,15 @@ megasas_free_fusion_context(struct megasas_instance *instance) fusion->load_balance_info_pages); } - if (is_vmalloc_addr(fusion)) - vfree(fusion); - else - free_pages((ulong)fusion, - instance->ctrl_context_pages); + if (fusion->log_to_span) { + if (is_vmalloc_addr(fusion->log_to_span)) + vfree(fusion->log_to_span); + else + free_pages((ulong)fusion->log_to_span, + fusion->log_to_span_pages); + } + + kfree(fusion); } } diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index 7c1f7ccf031da..a2b56913f3820 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -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; };