scsi: megaraid_sas: reduce size of fusion_context and use kmalloc for allocation
authorShivasharan S <shivasharan.srikanteshwara@broadcom.com>
Thu, 19 Oct 2017 09:48:53 +0000 (02:48 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 25 Oct 2017 08:55:25 +0000 (04:55 -0400)
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: Shu Wang <shuwang@redhat.com>
Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com>
Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_fusion.c
drivers/scsi/megaraid/megaraid_sas_fusion.h

index 5b36a01..1f34577 100644 (file)
@@ -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];
index 01d42eb..a805534 100644 (file)
@@ -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);
+       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 =
@@ -4546,11 +4557,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);
        }
 }
 
index 7c1f7cc..a2b5691 100644 (file)
@@ -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;
 };