Skip to content

Commit def3e8d

Browse files
shivasharan-smartinkpetersen
authored andcommitted
scsi: megaraid_sas: use vmalloc for crash dump buffers and driver's local RAID map
Driver's local RAID map is accessed frequently. We will first try to get memory from __get_free_pages. If this fails, fall back to using vmalloc. For crash dump buffers always prefer vmalloc. Signed-off-by: Kashyap Desai <[email protected]> Signed-off-by: Shivasharan S <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: Tomas Henzl <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 28661c8 commit def3e8d

File tree

3 files changed

+88
-46
lines changed

3 files changed

+88
-46
lines changed

drivers/scsi/megaraid/megaraid_sas.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2115,7 +2115,6 @@ struct megasas_instance {
21152115
u32 *crash_dump_buf;
21162116
dma_addr_t crash_dump_h;
21172117
void *crash_buf[MAX_CRASH_DUMP_SIZE];
2118-
u32 crash_buf_pages;
21192118
unsigned int fw_crash_buffer_size;
21202119
unsigned int fw_crash_state;
21212120
unsigned int fw_crash_buffer_offset;

drivers/scsi/megaraid/megaraid_sas_base.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include <linux/blkdev.h>
5050
#include <linux/mutex.h>
5151
#include <linux/poll.h>
52+
#include <linux/vmalloc.h>
5253

5354
#include <scsi/scsi.h>
5455
#include <scsi/scsi_cmnd.h>
@@ -6671,9 +6672,14 @@ static void megasas_detach_one(struct pci_dev *pdev)
66716672
fusion->max_map_sz,
66726673
fusion->ld_map[i],
66736674
fusion->ld_map_phys[i]);
6674-
if (fusion->ld_drv_map[i])
6675-
free_pages((ulong)fusion->ld_drv_map[i],
6676-
fusion->drv_map_pages);
6675+
if (fusion->ld_drv_map[i]) {
6676+
if (is_vmalloc_addr(fusion->ld_drv_map[i]))
6677+
vfree(fusion->ld_drv_map[i]);
6678+
else
6679+
free_pages((ulong)fusion->ld_drv_map[i],
6680+
fusion->drv_map_pages);
6681+
}
6682+
66776683
if (fusion->pd_seq_sync[i])
66786684
dma_free_coherent(&instance->pdev->dev,
66796685
pd_seq_map_sz,

drivers/scsi/megaraid/megaraid_sas_fusion.c

Lines changed: 79 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,80 @@ megasas_display_intel_branding(struct megasas_instance *instance)
12621262
}
12631263
}
12641264

1265+
/**
1266+
* megasas_allocate_raid_maps - Allocate memory for RAID maps
1267+
* @instance: Adapter soft state
1268+
*
1269+
* return: if success: return 0
1270+
* failed: return -ENOMEM
1271+
*/
1272+
static inline int megasas_allocate_raid_maps(struct megasas_instance *instance)
1273+
{
1274+
struct fusion_context *fusion;
1275+
int i = 0;
1276+
1277+
fusion = instance->ctrl_context;
1278+
1279+
fusion->drv_map_pages = get_order(fusion->drv_map_sz);
1280+
1281+
for (i = 0; i < 2; i++) {
1282+
fusion->ld_map[i] = NULL;
1283+
1284+
fusion->ld_drv_map[i] = (void *)
1285+
__get_free_pages(__GFP_ZERO | GFP_KERNEL,
1286+
fusion->drv_map_pages);
1287+
1288+
if (!fusion->ld_drv_map[i]) {
1289+
fusion->ld_drv_map[i] = vzalloc(fusion->drv_map_sz);
1290+
1291+
if (!fusion->ld_drv_map[i]) {
1292+
dev_err(&instance->pdev->dev,
1293+
"Could not allocate memory for local map"
1294+
" size requested: %d\n",
1295+
fusion->drv_map_sz);
1296+
goto ld_drv_map_alloc_fail;
1297+
}
1298+
}
1299+
}
1300+
1301+
for (i = 0; i < 2; i++) {
1302+
fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev,
1303+
fusion->max_map_sz,
1304+
&fusion->ld_map_phys[i],
1305+
GFP_KERNEL);
1306+
if (!fusion->ld_map[i]) {
1307+
dev_err(&instance->pdev->dev,
1308+
"Could not allocate memory for map info %s:%d\n",
1309+
__func__, __LINE__);
1310+
goto ld_map_alloc_fail;
1311+
}
1312+
}
1313+
1314+
return 0;
1315+
1316+
ld_map_alloc_fail:
1317+
for (i = 0; i < 2; i++) {
1318+
if (fusion->ld_map[i])
1319+
dma_free_coherent(&instance->pdev->dev,
1320+
fusion->max_map_sz,
1321+
fusion->ld_map[i],
1322+
fusion->ld_map_phys[i]);
1323+
}
1324+
1325+
ld_drv_map_alloc_fail:
1326+
for (i = 0; i < 2; i++) {
1327+
if (fusion->ld_drv_map[i]) {
1328+
if (is_vmalloc_addr(fusion->ld_drv_map[i]))
1329+
vfree(fusion->ld_drv_map[i]);
1330+
else
1331+
free_pages((ulong)fusion->ld_drv_map[i],
1332+
fusion->drv_map_pages);
1333+
}
1334+
}
1335+
1336+
return -ENOMEM;
1337+
}
1338+
12651339
/**
12661340
* megasas_init_adapter_fusion - Initializes the FW
12671341
* @instance: Adapter soft state
@@ -1381,45 +1455,14 @@ megasas_init_adapter_fusion(struct megasas_instance *instance)
13811455
instance->r1_ldio_hint_default = MR_R1_LDIO_PIGGYBACK_DEFAULT;
13821456
fusion->fast_path_io = 0;
13831457

1384-
fusion->drv_map_pages = get_order(fusion->drv_map_sz);
1385-
for (i = 0; i < 2; i++) {
1386-
fusion->ld_map[i] = NULL;
1387-
fusion->ld_drv_map[i] = (void *)__get_free_pages(GFP_KERNEL,
1388-
fusion->drv_map_pages);
1389-
if (!fusion->ld_drv_map[i]) {
1390-
dev_err(&instance->pdev->dev, "Could not allocate "
1391-
"memory for local map info for %d pages\n",
1392-
fusion->drv_map_pages);
1393-
if (i == 1)
1394-
free_pages((ulong)fusion->ld_drv_map[0],
1395-
fusion->drv_map_pages);
1396-
goto fail_ioc_init;
1397-
}
1398-
memset(fusion->ld_drv_map[i], 0,
1399-
((1 << PAGE_SHIFT) << fusion->drv_map_pages));
1400-
}
1401-
1402-
for (i = 0; i < 2; i++) {
1403-
fusion->ld_map[i] = dma_alloc_coherent(&instance->pdev->dev,
1404-
fusion->max_map_sz,
1405-
&fusion->ld_map_phys[i],
1406-
GFP_KERNEL);
1407-
if (!fusion->ld_map[i]) {
1408-
dev_err(&instance->pdev->dev, "Could not allocate memory "
1409-
"for map info\n");
1410-
goto fail_map_info;
1411-
}
1412-
}
1458+
if (megasas_allocate_raid_maps(instance))
1459+
goto fail_ioc_init;
14131460

14141461
if (!megasas_get_map_info(instance))
14151462
megasas_sync_map_info(instance);
14161463

14171464
return 0;
14181465

1419-
fail_map_info:
1420-
if (i == 1)
1421-
dma_free_coherent(&instance->pdev->dev, fusion->max_map_sz,
1422-
fusion->ld_map[0], fusion->ld_map_phys[0]);
14231466
fail_ioc_init:
14241467
megasas_free_cmds_fusion(instance);
14251468
fail_alloc_cmds:
@@ -3371,17 +3414,13 @@ megasas_alloc_host_crash_buffer(struct megasas_instance *instance)
33713414
{
33723415
unsigned int i;
33733416

3374-
instance->crash_buf_pages = get_order(CRASH_DMA_BUF_SIZE);
33753417
for (i = 0; i < MAX_CRASH_DUMP_SIZE; i++) {
3376-
instance->crash_buf[i] = (void *)__get_free_pages(GFP_KERNEL,
3377-
instance->crash_buf_pages);
3418+
instance->crash_buf[i] = vzalloc(CRASH_DMA_BUF_SIZE);
33783419
if (!instance->crash_buf[i]) {
33793420
dev_info(&instance->pdev->dev, "Firmware crash dump "
33803421
"memory allocation failed at index %d\n", i);
33813422
break;
33823423
}
3383-
memset(instance->crash_buf[i], 0,
3384-
((1 << PAGE_SHIFT) << instance->crash_buf_pages));
33853424
}
33863425
instance->drv_buf_alloc = i;
33873426
}
@@ -3393,12 +3432,10 @@ megasas_alloc_host_crash_buffer(struct megasas_instance *instance)
33933432
void
33943433
megasas_free_host_crash_buffer(struct megasas_instance *instance)
33953434
{
3396-
unsigned int i
3397-
;
3435+
unsigned int i;
33983436
for (i = 0; i < instance->drv_buf_alloc; i++) {
33993437
if (instance->crash_buf[i])
3400-
free_pages((ulong)instance->crash_buf[i],
3401-
instance->crash_buf_pages);
3438+
vfree(instance->crash_buf[i]);
34023439
}
34033440
instance->drv_buf_index = 0;
34043441
instance->drv_buf_alloc = 0;

0 commit comments

Comments
 (0)