summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérôme Glisse <jglisse@redhat.com>2019-05-22 16:39:45 -0400
committerJérôme Glisse <jglisse@redhat.com>2019-05-22 17:19:11 -0400
commitfa407f97a91ced623dc522d7afbd6254dbc3d457 (patch)
treef4422dabaf29b67799c0f2bb534f013bd15a3565
parent9ede03e01e103b2d641ecf9ac5d1de4a99e3819e (diff)
vhost-scsi: use put_user_page() for pages coming from get_user_page*()
For pages coming from GUP (any get_user_page*() function) we want to release the page reference with put_user_page(). Signed-off-by: Jérôme Glisse <jglisse@redhat.com> Cc: virtualization@lists.linux-foundation.org Cc: linux-fsdevel@vger.kernel.org Cc: linux-block@vger.kernel.org Cc: linux-mm@kvack.org Cc: John Hubbard <jhubbard@nvidia.com> Cc: Jan Kara <jack@suse.cz> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Johannes Thumshirn <jthumshirn@suse.de> Cc: Christoph Hellwig <hch@lst.de> Cc: Jens Axboe <axboe@kernel.dk> Cc: Ming Lei <ming.lei@redhat.com> Cc: Dave Chinner <david@fromorbit.com> Cc: Jason Gunthorpe <jgg@ziepe.ca> Cc: Matthew Wilcox <willy@infradead.org> Cc: Boaz Harrosh <boaz@plexistor.com> Cc: Miklos Szeredi <miklos@szeredi.hu> Cc: "Michael S. Tsirkin" <mst@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--drivers/vhost/scsi.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index c090d177bd75..c007bdbc49f2 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -323,11 +323,11 @@ static void vhost_scsi_release_cmd(struct se_cmd *se_cmd)
if (tv_cmd->tvc_sgl_count) {
for (i = 0; i < tv_cmd->tvc_sgl_count; i++)
- put_page(sg_page(&tv_cmd->tvc_sgl[i]));
+ put_user_page(sg_page(&tv_cmd->tvc_sgl[i]));
}
if (tv_cmd->tvc_prot_sgl_count) {
for (i = 0; i < tv_cmd->tvc_prot_sgl_count; i++)
- put_page(sg_page(&tv_cmd->tvc_prot_sgl[i]));
+ put_user_page(sg_page(&tv_cmd->tvc_prot_sgl[i]));
}
vhost_scsi_put_inflight(tv_cmd->inflight);
@@ -624,6 +624,16 @@ vhost_scsi_map_to_sgl(struct vhost_scsi_cmd *cmd,
size_t offset;
unsigned int npages = 0;
+ /*
+ * Here in all cases we should have an IOVEC which use GUP. If that is
+ * not the case then we will wrongly call put_user_page() and the page
+ * refcount will go wrong (this is in vhost_scsi_release_cmd())
+ *
+ * So offer a way to debug this and make sure no one forget about this
+ * assumption with a BUG_ON() (the A team to the rescue !)
+ */
+ BUG_ON(!iov_iter_get_pages_use_gup(iter));
+
bytes = iov_iter_get_pages(iter, pages, LONG_MAX,
VHOST_SCSI_PREALLOC_UPAGES, &offset);
/* No pages were pinned */
@@ -675,7 +685,7 @@ vhost_scsi_iov_to_sgl(struct vhost_scsi_cmd *cmd, bool write,
while (p < sg) {
struct page *page = sg_page(p++);
if (page)
- put_page(page);
+ put_user_page(page);
}
return ret;
}