diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2013-06-29 17:59:15 +0900 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-07-09 09:21:38 +0100 |
commit | fc3fc352b6e7a6452596f8a13cedeaa6bcfe9689 (patch) | |
tree | ddb3a7a4168c5a6ab904ad0573f39315f392f164 /drivers/scsi | |
parent | 518d9df87105a078984c90c75cf6e7f67e3c928c (diff) | |
download | linux-stable-fc3fc352b6e7a6452596f8a13cedeaa6bcfe9689.tar.gz linux-stable-fc3fc352b6e7a6452596f8a13cedeaa6bcfe9689.tar.bz2 linux-stable-fc3fc352b6e7a6452596f8a13cedeaa6bcfe9689.zip |
[SCSI] scsi_debug: fix incorrectly nested kmap_atomic()
In the function prot_verify_write(), kmap_atomic()/kunmap_atomic() for
data page and kmap_atomic()/kunmap_atomic() for protection information
page are not nested each other.
It worked perfectly before commit 3e4d3af501cccdc8a8cca41bdbe57d54ad7e7e73
("mm: stack based kmap_atomic()"). Because the kmap_atomic slot KM_IRQ0
was used for data page and the slot KM_IRQ1 was used for protection page.
But KM_types are gone and kmap_atomic() is using stack based implementation.
So two different kmap_atomic() usages must be strictly nested now.
This change ensures kmap_atomic() usage is strictly nested.
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Acked-by: Douglas Gilbert <dgilbert@interlog.com>
Acked-by: "Martin K. Petersen" <martin.petersen@oracle.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/scsi_debug.c | 7 |
1 files changed, 3 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d51bddde5b1f..bcf73e44d2fb 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -1891,12 +1891,12 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, BUG_ON(scsi_sg_count(SCpnt) == 0); BUG_ON(scsi_prot_sg_count(SCpnt) == 0); - paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; ppage_offset = 0; /* For each data page */ scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) { daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset; + paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; /* For each sector-sized chunk in data page */ for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) { @@ -1980,19 +1980,18 @@ static int prot_verify_write(struct scsi_cmnd *SCpnt, sector_t start_sec, ppage_offset += sizeof(struct sd_dif_tuple); } + kunmap_atomic(paddr); kunmap_atomic(daddr); } - kunmap_atomic(paddr); - dix_writes++; return 0; out: dif_errors++; - kunmap_atomic(daddr); kunmap_atomic(paddr); + kunmap_atomic(daddr); return ret; } |