NVMe: Correct sg list setup in nvme_map_user_pages
authorMatthew Wilcox <matthew.r.wilcox@intel.com>
Tue, 13 Sep 2011 21:01:39 +0000 (17:01 -0400)
committerMatthew Wilcox <matthew.r.wilcox@intel.com>
Fri, 4 Nov 2011 19:53:04 +0000 (15:53 -0400)
Our SG list was constructed to always fill the entire first page, even
if that was more than the length of the I/O.  This is probably harmless,
but some IOMMUs might do something bad.

Correcting the first call to sg_set_page() made it look a lot closer to
the sg_set_page() in the loop, so fold the first call to sg_set_page()
into the loop.

Reported-by: Nisheeth Bhat <nisheeth.bhat@intel.com>
Signed-off-by: Matthew Wilcox <willy@linux.intel.com>
drivers/block/nvme.c

index 0956e124152047ef9ef5cc6c66137a730722444f..5843409cac6d1003c9bc8b4dd46126eca941063d 100644 (file)
@@ -996,11 +996,11 @@ static int nvme_map_user_pages(struct nvme_dev *dev, int write,
 
        sg = kcalloc(count, sizeof(*sg), GFP_KERNEL);
        sg_init_table(sg, count);
-       sg_set_page(&sg[0], pages[0], PAGE_SIZE - offset, offset);
-       length -= (PAGE_SIZE - offset);
-       for (i = 1; i < count; i++) {
-               sg_set_page(&sg[i], pages[i], min_t(int, length, PAGE_SIZE), 0);
-               length -= PAGE_SIZE;
+       for (i = 0; i < count; i++) {
+               sg_set_page(&sg[i], pages[i],
+                               min_t(int, length, PAGE_SIZE - offset), offset);
+               length -= (PAGE_SIZE - offset);
+               offset = 0;
        }
 
        err = -ENOMEM;