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: 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>
This commit is contained in:
Родитель
f369a31578
Коммит
2dd689c808
|
@ -2218,7 +2218,6 @@ struct megasas_instance {
|
||||||
|
|
||||||
/* Ptr to hba specific information */
|
/* Ptr to hba specific information */
|
||||||
void *ctrl_context;
|
void *ctrl_context;
|
||||||
u32 ctrl_context_pages;
|
|
||||||
struct megasas_ctrl_info *ctrl_info;
|
struct megasas_ctrl_info *ctrl_info;
|
||||||
unsigned int msix_vectors;
|
unsigned int msix_vectors;
|
||||||
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
|
struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
|
||||||
|
|
|
@ -4502,20 +4502,31 @@ megasas_alloc_fusion_context(struct megasas_instance *instance)
|
||||||
{
|
{
|
||||||
struct fusion_context *fusion;
|
struct fusion_context *fusion;
|
||||||
|
|
||||||
instance->ctrl_context_pages = get_order(sizeof(struct fusion_context));
|
instance->ctrl_context = kzalloc(sizeof(struct fusion_context),
|
||||||
instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
|
GFP_KERNEL);
|
||||||
instance->ctrl_context_pages);
|
|
||||||
if (!instance->ctrl_context) {
|
if (!instance->ctrl_context) {
|
||||||
/* fall back to using vmalloc for fusion_context */
|
dev_err(&instance->pdev->dev, "Failed from %s %d\n",
|
||||||
instance->ctrl_context = vzalloc(sizeof(struct fusion_context));
|
__func__, __LINE__);
|
||||||
if (!instance->ctrl_context) {
|
return -ENOMEM;
|
||||||
dev_err(&instance->pdev->dev, "Failed from %s %d\n", __func__, __LINE__);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fusion = instance->ctrl_context;
|
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 *
|
fusion->load_balance_info_pages = get_order(MAX_LOGICAL_DRIVES_EXT *
|
||||||
sizeof(struct LD_LOAD_BALANCE_INFO));
|
sizeof(struct LD_LOAD_BALANCE_INFO));
|
||||||
fusion->load_balance_info =
|
fusion->load_balance_info =
|
||||||
|
@ -4546,11 +4557,15 @@ megasas_free_fusion_context(struct megasas_instance *instance)
|
||||||
fusion->load_balance_info_pages);
|
fusion->load_balance_info_pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_vmalloc_addr(fusion))
|
if (fusion->log_to_span) {
|
||||||
vfree(fusion);
|
if (is_vmalloc_addr(fusion->log_to_span))
|
||||||
else
|
vfree(fusion->log_to_span);
|
||||||
free_pages((ulong)fusion,
|
else
|
||||||
instance->ctrl_context_pages);
|
free_pages((ulong)fusion->log_to_span,
|
||||||
|
fusion->log_to_span_pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
kfree(fusion);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1312,7 +1312,8 @@ struct fusion_context {
|
||||||
u8 fast_path_io;
|
u8 fast_path_io;
|
||||||
struct LD_LOAD_BALANCE_INFO *load_balance_info;
|
struct LD_LOAD_BALANCE_INFO *load_balance_info;
|
||||||
u32 load_balance_info_pages;
|
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;
|
struct LD_STREAM_DETECT **stream_detect_by_ld;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче