diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2013-06-29 04:59:15 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2013-07-09 04:21:38 -0400 |
commit | fc3fc352b6e7a6452596f8a13cedeaa6bcfe9689 (patch) | |
tree | ddb3a7a4168c5a6ab904ad0573f39315f392f164 /drivers/scsi | |
parent | 518d9df87105a078984c90c75cf6e7f67e3c928c (diff) |
[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, | |||
1891 | BUG_ON(scsi_sg_count(SCpnt) == 0); | 1891 | BUG_ON(scsi_sg_count(SCpnt) == 0); |
1892 | BUG_ON(scsi_prot_sg_count(SCpnt) == 0); | 1892 | BUG_ON(scsi_prot_sg_count(SCpnt) == 0); |
1893 | 1893 | ||
1894 | paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; | ||
1895 | ppage_offset = 0; | 1894 | ppage_offset = 0; |
1896 | 1895 | ||
1897 | /* For each data page */ | 1896 | /* For each data page */ |
1898 | scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) { | 1897 | scsi_for_each_sg(SCpnt, dsgl, scsi_sg_count(SCpnt), i) { |
1899 | daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset; | 1898 | daddr = kmap_atomic(sg_page(dsgl)) + dsgl->offset; |
1899 | paddr = kmap_atomic(sg_page(psgl)) + psgl->offset; | ||
1900 | 1900 | ||
1901 | /* For each sector-sized chunk in data page */ | 1901 | /* For each sector-sized chunk in data page */ |
1902 | for (j = 0; j < dsgl->length; j += scsi_debug_sector_size) { | 1902 | 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, | |||
1980 | ppage_offset += sizeof(struct sd_dif_tuple); | 1980 | ppage_offset += sizeof(struct sd_dif_tuple); |
1981 | } | 1981 | } |
1982 | 1982 | ||
1983 | kunmap_atomic(paddr); | ||
1983 | kunmap_atomic(daddr); | 1984 | kunmap_atomic(daddr); |
1984 | } | 1985 | } |
1985 | 1986 | ||
1986 | kunmap_atomic(paddr); | ||
1987 | |||
1988 | dix_writes++; | 1987 | dix_writes++; |
1989 | 1988 | ||
1990 | return 0; | 1989 | return 0; |
1991 | 1990 | ||
1992 | out: | 1991 | out: |
1993 | dif_errors++; | 1992 | dif_errors++; |
1994 | kunmap_atomic(daddr); | ||
1995 | kunmap_atomic(paddr); | 1993 | kunmap_atomic(paddr); |
1994 | kunmap_atomic(daddr); | ||
1996 | return ret; | 1995 | return ret; |
1997 | } | 1996 | } |
1998 | 1997 | ||