Skip to content

Commit b5f3bc3

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix inconsistent DMA mem alloc/free
GPNFT command allocates 2 buffer for switch query. On completion, the same buffers were freed using different size, instead of using original size at the time of allocation. This patch saves the size of the request and response buffers and uses that to free them. Following stack trace can be seen when using debug kernel dump_stack+0x19/0x1b __warn+0xd8/0x100 warn_slowpath_fmt+0x5f/0x80 check_unmap+0xfb/0xa20 debug_dma_free_coherent+0x110/0x160 qla24xx_sp_unmap+0x131/0x1e0 [qla2xxx] qla24xx_async_gnnft_done+0xb6/0x550 [qla2xxx] qla2x00_do_work+0x1ec/0x9f0 [qla2xxx] Cc: <[email protected]> # v4.17+ Fixes: 33b2835 ("scsi: qla2xxx: Fix Async GPN_FT for FCP and FC-NVMe scan") Reported-by: Ewan D. Milne <[email protected]> Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Himanshu Madhani <[email protected]> Signed-off-by: Himanshu Madhani <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 26b5b87 commit b5f3bc3

File tree

2 files changed

+28
-14
lines changed

2 files changed

+28
-14
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,8 @@ struct ct_arg {
361361
dma_addr_t rsp_dma;
362362
u32 req_size;
363363
u32 rsp_size;
364+
u32 req_allocated_size;
365+
u32 rsp_allocated_size;
364366
void *req;
365367
void *rsp;
366368
port_id_t id;

drivers/scsi/qla2xxx/qla_gs.c

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -556,15 +556,15 @@ static void qla2x00_async_sns_sp_done(void *s, int rc)
556556
/* please ignore kernel warning. otherwise, we have mem leak. */
557557
if (sp->u.iocb_cmd.u.ctarg.req) {
558558
dma_free_coherent(&vha->hw->pdev->dev,
559-
sizeof(struct ct_sns_pkt),
559+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
560560
sp->u.iocb_cmd.u.ctarg.req,
561561
sp->u.iocb_cmd.u.ctarg.req_dma);
562562
sp->u.iocb_cmd.u.ctarg.req = NULL;
563563
}
564564

565565
if (sp->u.iocb_cmd.u.ctarg.rsp) {
566566
dma_free_coherent(&vha->hw->pdev->dev,
567-
sizeof(struct ct_sns_pkt),
567+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
568568
sp->u.iocb_cmd.u.ctarg.rsp,
569569
sp->u.iocb_cmd.u.ctarg.rsp_dma);
570570
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
@@ -617,6 +617,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
617617
sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
618618
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
619619
GFP_KERNEL);
620+
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
620621
if (!sp->u.iocb_cmd.u.ctarg.req) {
621622
ql_log(ql_log_warn, vha, 0xd041,
622623
"%s: Failed to allocate ct_sns request.\n",
@@ -627,6 +628,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
627628
sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
628629
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
629630
GFP_KERNEL);
631+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
630632
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
631633
ql_log(ql_log_warn, vha, 0xd042,
632634
"%s: Failed to allocate ct_sns request.\n",
@@ -712,6 +714,7 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
712714
sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
713715
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
714716
GFP_KERNEL);
717+
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
715718
if (!sp->u.iocb_cmd.u.ctarg.req) {
716719
ql_log(ql_log_warn, vha, 0xd041,
717720
"%s: Failed to allocate ct_sns request.\n",
@@ -722,6 +725,7 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
722725
sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
723726
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
724727
GFP_KERNEL);
728+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
725729
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
726730
ql_log(ql_log_warn, vha, 0xd042,
727731
"%s: Failed to allocate ct_sns request.\n",
@@ -802,6 +806,7 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id,
802806
sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
803807
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
804808
GFP_KERNEL);
809+
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
805810
if (!sp->u.iocb_cmd.u.ctarg.req) {
806811
ql_log(ql_log_warn, vha, 0xd041,
807812
"%s: Failed to allocate ct_sns request.\n",
@@ -812,6 +817,7 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id,
812817
sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
813818
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
814819
GFP_KERNEL);
820+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
815821
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
816822
ql_log(ql_log_warn, vha, 0xd042,
817823
"%s: Failed to allocate ct_sns request.\n",
@@ -909,6 +915,7 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha)
909915
sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
910916
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
911917
GFP_KERNEL);
918+
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
912919
if (!sp->u.iocb_cmd.u.ctarg.req) {
913920
ql_log(ql_log_warn, vha, 0xd041,
914921
"%s: Failed to allocate ct_sns request.\n",
@@ -919,6 +926,7 @@ static int qla_async_rsnn_nn(scsi_qla_host_t *vha)
919926
sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
920927
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
921928
GFP_KERNEL);
929+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
922930
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
923931
ql_log(ql_log_warn, vha, 0xd042,
924932
"%s: Failed to allocate ct_sns request.\n",
@@ -3388,14 +3396,14 @@ void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
33883396
{
33893397
if (sp->u.iocb_cmd.u.ctarg.req) {
33903398
dma_free_coherent(&vha->hw->pdev->dev,
3391-
sizeof(struct ct_sns_pkt),
3399+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
33923400
sp->u.iocb_cmd.u.ctarg.req,
33933401
sp->u.iocb_cmd.u.ctarg.req_dma);
33943402
sp->u.iocb_cmd.u.ctarg.req = NULL;
33953403
}
33963404
if (sp->u.iocb_cmd.u.ctarg.rsp) {
33973405
dma_free_coherent(&vha->hw->pdev->dev,
3398-
sizeof(struct ct_sns_pkt),
3406+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
33993407
sp->u.iocb_cmd.u.ctarg.rsp,
34003408
sp->u.iocb_cmd.u.ctarg.rsp_dma);
34013409
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
@@ -3596,14 +3604,14 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res)
35963604
/* please ignore kernel warning. otherwise, we have mem leak. */
35973605
if (sp->u.iocb_cmd.u.ctarg.req) {
35983606
dma_free_coherent(&vha->hw->pdev->dev,
3599-
sizeof(struct ct_sns_pkt),
3607+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
36003608
sp->u.iocb_cmd.u.ctarg.req,
36013609
sp->u.iocb_cmd.u.ctarg.req_dma);
36023610
sp->u.iocb_cmd.u.ctarg.req = NULL;
36033611
}
36043612
if (sp->u.iocb_cmd.u.ctarg.rsp) {
36053613
dma_free_coherent(&vha->hw->pdev->dev,
3606-
sizeof(struct ct_sns_pkt),
3614+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
36073615
sp->u.iocb_cmd.u.ctarg.rsp,
36083616
sp->u.iocb_cmd.u.ctarg.rsp_dma);
36093617
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
@@ -3654,6 +3662,7 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
36543662
sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
36553663
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
36563664
GFP_KERNEL);
3665+
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
36573666
if (!sp->u.iocb_cmd.u.ctarg.req) {
36583667
ql_log(ql_log_warn, vha, 0xd041,
36593668
"Failed to allocate ct_sns request.\n");
@@ -3663,6 +3672,7 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
36633672
sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
36643673
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
36653674
GFP_KERNEL);
3675+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
36663676
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
36673677
ql_log(ql_log_warn, vha, 0xd042,
36683678
"Failed to allocate ct_sns request.\n");
@@ -4142,14 +4152,14 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
41424152
*/
41434153
if (sp->u.iocb_cmd.u.ctarg.req) {
41444154
dma_free_coherent(&vha->hw->pdev->dev,
4145-
sizeof(struct ct_sns_pkt),
4155+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
41464156
sp->u.iocb_cmd.u.ctarg.req,
41474157
sp->u.iocb_cmd.u.ctarg.req_dma);
41484158
sp->u.iocb_cmd.u.ctarg.req = NULL;
41494159
}
41504160
if (sp->u.iocb_cmd.u.ctarg.rsp) {
41514161
dma_free_coherent(&vha->hw->pdev->dev,
4152-
sizeof(struct ct_sns_pkt),
4162+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
41534163
sp->u.iocb_cmd.u.ctarg.rsp,
41544164
sp->u.iocb_cmd.u.ctarg.rsp_dma);
41554165
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
@@ -4179,14 +4189,14 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
41794189
/* please ignore kernel warning. Otherwise, we have mem leak. */
41804190
if (sp->u.iocb_cmd.u.ctarg.req) {
41814191
dma_free_coherent(&vha->hw->pdev->dev,
4182-
sizeof(struct ct_sns_pkt),
4192+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
41834193
sp->u.iocb_cmd.u.ctarg.req,
41844194
sp->u.iocb_cmd.u.ctarg.req_dma);
41854195
sp->u.iocb_cmd.u.ctarg.req = NULL;
41864196
}
41874197
if (sp->u.iocb_cmd.u.ctarg.rsp) {
41884198
dma_free_coherent(&vha->hw->pdev->dev,
4189-
sizeof(struct ct_sns_pkt),
4199+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
41904200
sp->u.iocb_cmd.u.ctarg.rsp,
41914201
sp->u.iocb_cmd.u.ctarg.rsp_dma);
41924202
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
@@ -4281,14 +4291,14 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
42814291
done_free_sp:
42824292
if (sp->u.iocb_cmd.u.ctarg.req) {
42834293
dma_free_coherent(&vha->hw->pdev->dev,
4284-
sizeof(struct ct_sns_pkt),
4294+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
42854295
sp->u.iocb_cmd.u.ctarg.req,
42864296
sp->u.iocb_cmd.u.ctarg.req_dma);
42874297
sp->u.iocb_cmd.u.ctarg.req = NULL;
42884298
}
42894299
if (sp->u.iocb_cmd.u.ctarg.rsp) {
42904300
dma_free_coherent(&vha->hw->pdev->dev,
4291-
sizeof(struct ct_sns_pkt),
4301+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
42924302
sp->u.iocb_cmd.u.ctarg.rsp,
42934303
sp->u.iocb_cmd.u.ctarg.rsp_dma);
42944304
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
@@ -4349,6 +4359,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
43494359
sp->u.iocb_cmd.u.ctarg.req = dma_zalloc_coherent(
43504360
&vha->hw->pdev->dev, sizeof(struct ct_sns_pkt),
43514361
&sp->u.iocb_cmd.u.ctarg.req_dma, GFP_KERNEL);
4362+
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
43524363
if (!sp->u.iocb_cmd.u.ctarg.req) {
43534364
ql_log(ql_log_warn, vha, 0xffff,
43544365
"Failed to allocate ct_sns request.\n");
@@ -4366,6 +4377,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
43664377
sp->u.iocb_cmd.u.ctarg.rsp = dma_zalloc_coherent(
43674378
&vha->hw->pdev->dev, rspsz,
43684379
&sp->u.iocb_cmd.u.ctarg.rsp_dma, GFP_KERNEL);
4380+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
43694381
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
43704382
ql_log(ql_log_warn, vha, 0xffff,
43714383
"Failed to allocate ct_sns request.\n");
@@ -4425,14 +4437,14 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
44254437
done_free_sp:
44264438
if (sp->u.iocb_cmd.u.ctarg.req) {
44274439
dma_free_coherent(&vha->hw->pdev->dev,
4428-
sizeof(struct ct_sns_pkt),
4440+
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
44294441
sp->u.iocb_cmd.u.ctarg.req,
44304442
sp->u.iocb_cmd.u.ctarg.req_dma);
44314443
sp->u.iocb_cmd.u.ctarg.req = NULL;
44324444
}
44334445
if (sp->u.iocb_cmd.u.ctarg.rsp) {
44344446
dma_free_coherent(&vha->hw->pdev->dev,
4435-
sizeof(struct ct_sns_pkt),
4447+
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
44364448
sp->u.iocb_cmd.u.ctarg.rsp,
44374449
sp->u.iocb_cmd.u.ctarg.rsp_dma);
44384450
sp->u.iocb_cmd.u.ctarg.rsp = NULL;

0 commit comments

Comments
 (0)