From: "Michael S. Tsirkin" <mst@redhat.com>
To: linux-kernel@vger.kernel.org, virtualization@lists.linux-foundation.org
Cc: Rusty Russell <rusty@rustcorp.com.au>,
cornelia.huck@de.ibm.com,
virtualization@lists.linux-foundation.org
Subject: [PATCH v3 15/16] virtio_pci_modern: reduce number of mappings
Date: Wed, 14 Jan 2015 19:28:18 +0200 [thread overview]
Message-ID: <1421256142-11512-16-git-send-email-mst@redhat.com> (raw)
In-Reply-To: <1421256142-11512-1-git-send-email-mst@redhat.com>
We don't know the # of VQs that drivers are going to use so it's hard to
predict how much memory we'll need to map. However, the relevant
capability does give us an upper limit.
If that's below a page, we can reduce the number of required
mappings by mapping it all once ahead of the time.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
drivers/virtio/virtio_pci_common.h | 3 ++
drivers/virtio/virtio_pci_modern.c | 57 ++++++++++++++++++++++++++++++++------
2 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/drivers/virtio/virtio_pci_common.h b/drivers/virtio/virtio_pci_common.h
index 610c43f..d391805 100644
--- a/drivers/virtio/virtio_pci_common.h
+++ b/drivers/virtio/virtio_pci_common.h
@@ -62,8 +62,11 @@ struct virtio_pci_device {
struct virtio_pci_common_cfg __iomem *common;
/* Device-specific data (non-legacy mode) */
void __iomem *device;
+ /* Base of vq notifications (non-legacy mode). */
+ void __iomem *notify_base;
/* So we can sanity-check accesses. */
+ size_t notify_len;
size_t device_len;
/* Capability for when we need to map notifications per-vq. */
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c
index 5e0d309..9c000e9a 100644
--- a/drivers/virtio/virtio_pci_modern.c
+++ b/drivers/virtio/virtio_pci_modern.c
@@ -333,10 +333,26 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
iowrite64_twopart(virt_to_phys(virtqueue_get_used(vq)),
&cfg->queue_used_lo, &cfg->queue_used_hi);
- vq->priv = (void __force *)map_capability(vp_dev->pci_dev,
- vp_dev->notify_map_cap, 2, 2,
- off * vp_dev->notify_offset_multiplier, 2,
- NULL);
+ if (vp_dev->notify_base) {
+ /* offset should not wrap */
+ if ((u64)off * vp_dev->notify_offset_multiplier + 2
+ > vp_dev->notify_len) {
+ dev_warn(&vp_dev->pci_dev->dev,
+ "bad notification offset %u (x %u) "
+ "for queue %u > %zd",
+ off, vp_dev->notify_offset_multiplier,
+ index, vp_dev->notify_len);
+ err = -EINVAL;
+ goto err_map_notify;
+ }
+ vq->priv = (void __force *)vp_dev->notify_base +
+ off * vp_dev->notify_offset_multiplier;
+ } else {
+ vq->priv = (void __force *)map_capability(vp_dev->pci_dev,
+ vp_dev->notify_map_cap, 2, 2,
+ off * vp_dev->notify_offset_multiplier, 2,
+ NULL);
+ }
if (!vq->priv) {
err = -ENOMEM;
@@ -355,7 +371,8 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
return vq;
err_assign_vector:
- pci_iounmap(vp_dev->pci_dev, (void __iomem __force *)vq->priv);
+ if (!vp_dev->notify_base)
+ pci_iounmap(vp_dev->pci_dev, (void __iomem __force *)vq->priv);
err_map_notify:
vring_del_virtqueue(vq);
err_new_queue:
@@ -400,7 +417,8 @@ static void del_vq(struct virtio_pci_vq_info *info)
ioread16(&vp_dev->common->queue_msix_vector);
}
- pci_iounmap(vp_dev->pci_dev, (void __force __iomem *)vq->priv);
+ if (!vp_dev->notify_base)
+ pci_iounmap(vp_dev->pci_dev, (void __force __iomem *)vq->priv);
vring_del_virtqueue(vq);
@@ -536,6 +554,7 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
struct pci_dev *pci_dev = vp_dev->pci_dev;
int err, common, isr, notify, device;
u32 notify_length;
+ u32 notify_offset;
check_offsets();
@@ -602,13 +621,30 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
notify + offsetof(struct virtio_pci_notify_cap,
notify_off_multiplier),
&vp_dev->notify_offset_multiplier);
- /* Read notify length from config space. */
+ /* Read notify length and offset from config space. */
pci_read_config_dword(pci_dev,
notify + offsetof(struct virtio_pci_notify_cap,
cap.length),
¬ify_length);
- vp_dev->notify_map_cap = notify;
+ pci_read_config_dword(pci_dev,
+ notify + offsetof(struct virtio_pci_notify_cap,
+ cap.length),
+ ¬ify_offset);
+
+ /* We don't know how many VQs we'll map, ahead of the time.
+ * If notify length is small, map it all now.
+ * Otherwise, map each VQ individually later.
+ */
+ if ((u64)notify_length + (notify_offset % PAGE_SIZE) <= PAGE_SIZE) {
+ vp_dev->notify_base = map_capability(pci_dev, notify, 2, 2,
+ 0, notify_length,
+ &vp_dev->notify_len);
+ if (!vp_dev->notify_base)
+ goto err_map_notify;
+ } else {
+ vp_dev->notify_map_cap = notify;
+ }
/* Again, we don't know how much we should map, but PAGE_SIZE
* is more than enough for all existing devices.
@@ -630,6 +666,9 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
return 0;
err_map_device:
+ if (vp_dev->notify_base)
+ pci_iounmap(pci_dev, vp_dev->notify_base);
+err_map_notify:
pci_iounmap(pci_dev, vp_dev->isr);
err_map_isr:
pci_iounmap(pci_dev, vp_dev->common);
@@ -643,6 +682,8 @@ void virtio_pci_modern_remove(struct virtio_pci_device *vp_dev)
if (vp_dev->device)
pci_iounmap(pci_dev, vp_dev->device);
+ if (vp_dev->notify_base)
+ pci_iounmap(pci_dev, vp_dev->notify_base);
pci_iounmap(pci_dev, vp_dev->isr);
pci_iounmap(pci_dev, vp_dev->common);
}
--
MST
next prev parent reply other threads:[~2015-01-14 17:29 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-14 17:27 [PATCH v3 00/16] virtio-pci: towards virtio 1.0 guest support Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 01/16] virtio_pci: drop virtio_config dependency Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 02/16] virtio/9p: verify device has config space Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 03/16] virtio/blk: " Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 04/16] virtio/console: " Michael S. Tsirkin
2015-01-20 10:40 ` Amit Shah
2015-01-20 11:09 ` Michael S. Tsirkin
2015-01-21 6:14 ` Amit Shah
2015-01-21 6:44 ` Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 05/16] virtio/net: " Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 06/16] virtio/scsi: " Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 07/16] virtio/balloon: " Michael S. Tsirkin
2015-01-14 17:27 ` [PATCH v3 08/16] mn10300: drop dead code Michael S. Tsirkin
2015-01-23 23:08 ` Bjorn Helgaas
2015-01-14 17:27 ` [PATCH v3 09/16] pci: add pci_iomap_range Michael S. Tsirkin
2015-01-23 23:08 ` Bjorn Helgaas
2015-01-14 17:27 ` [PATCH v3 10/16] s390: " Michael S. Tsirkin
2015-01-16 10:11 ` Sebastian Ott
2015-01-21 0:43 ` Rusty Russell
2015-01-14 17:28 ` [PATCH v3 11/16] virtio_pci: move probe/remove code to common Michael S. Tsirkin
2015-01-14 17:28 ` [PATCH v3 12/16] virtio-pci: define layout for virtio 1.0 Michael S. Tsirkin
2015-01-14 17:28 ` [PATCH v3 13/16] virtio_pci: modern driver Michael S. Tsirkin
2015-01-14 17:28 ` [PATCH v3 14/16] virtio_pci: macros for PCI layout offsets Michael S. Tsirkin
2015-01-14 17:28 ` Michael S. Tsirkin [this message]
2015-01-14 17:28 ` [PATCH v3 16/16] virtio_pci_modern: support devices with no config Michael S. Tsirkin
2015-01-15 21:18 ` [PATCH v3 00/16] virtio-pci: towards virtio 1.0 guest support Gerd Hoffmann
2015-01-15 21:32 ` Michael S. Tsirkin
2015-01-16 8:32 ` Gerd Hoffmann
2015-01-16 8:45 ` Michael S. Tsirkin
2015-01-16 13:27 ` Gerd Hoffmann
2015-01-19 10:54 ` Gerd Hoffmann
2015-01-20 16:38 ` Michael S. Tsirkin
2015-01-19 11:07 ` Gerd Hoffmann
2015-01-19 22:11 ` Michael S. Tsirkin
2015-01-20 16:32 ` Michael S. Tsirkin
2015-01-21 11:31 ` Gerd Hoffmann
2015-01-21 11:36 ` Michael S. Tsirkin
2015-01-21 13:43 ` Gerd Hoffmann
2015-01-21 14:19 ` Michael S. Tsirkin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1421256142-11512-16-git-send-email-mst@redhat.com \
--to=mst@redhat.com \
--cc=cornelia.huck@de.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=rusty@rustcorp.com.au \
--cc=virtualization@lists.linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).