virtio: Use spin_lock_irqsave/restore for virtio-pci
Subsystems (6)
PATCH 1/4 virtio: Use spin_lock_irqsave/restore for virtio-pci
From: Anthony Liguori <[email protected]>
virtio-pci acquires its spin lock in an interrupt context so it's necessary to use spin_lock_irqsave/restore variants. This patch fixes guest SMP when using virtio devices in KVM.
--- drivers/virtio/virtio_pci.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/virtio/virtio_pci.c +9 -6
@@ -177,6 +177,7 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)struct virtio_pci_device *vp_dev = opaque;struct virtio_pci_vq_info *info;irqreturn_t ret =IRQ_NONE ; +unsigned long flags;u8 isr;/* reading the ISR has the effect of also clearing it so it's very
@@ -197,12 +198,12 @@ static irqreturn_t vp_interrupt(int irq, void *opaque) drv->config_changed (&vp_dev->vdev); } -spin_lock (&vp_dev->lock); +spin_lock_irqsave (&vp_dev->lock, flags);list_for_each_entry (info, &vp_dev->virtqueues, node) {if (vring_interrupt (irq, info->vq) ==IRQ_HANDLED ) ret =IRQ_HANDLED ; } -spin_unlock (&vp_dev->lock); +spin_unlock_irqrestore (&vp_dev->lock, flags);return ret; }
@@ -214,6 +215,7 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index,struct virtio_pci_device *vp_dev =to_vp_device (vdev);struct virtio_pci_vq_info *info;struct virtqueue *vq; +unsigned long flags;u16 num;int err;
@@ -255,9 +257,9 @@ static struct virtqueue *vp_find_vq(struct virtio_device *vdev, unsigned index, vq->priv = info; info->vq = vq; -spin_lock (&vp_dev->lock); +spin_lock_irqsave (&vp_dev->lock, flags);list_add (&info->node, &vp_dev->virtqueues); -spin_unlock (&vp_dev->lock); +spin_unlock_irqrestore (&vp_dev->lock, flags);return vq;
@@ -274,10 +276,11 @@ static void vp_del_vq(struct virtqueue *vq) {struct virtio_pci_device *vp_dev =to_vp_device (vq->vdev);struct virtio_pci_vq_info *info = vq->priv; +unsigned long flags; -spin_lock (&vp_dev->lock); +spin_lock_irqsave (&vp_dev->lock, flags);list_del (&info->node); -spin_unlock (&vp_dev->lock); +spin_unlock_irqrestore (&vp_dev->lock, flags);vring_del_virtqueue (vq);
PATCH 2/4 virtio: Fix sysfs bits to have proper block symlink
From: Jeremy Katz <[email protected]>
Fix up so that the virtio_blk devices in sysfs link correctly to their block device. This then allows them to be detected by hal, etc
--- drivers/block/virtio_blk.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/virtio_blk.c +1 -0
@@ -238,6 +238,7 @@ static int virtblk_probe(struct virtio_device *vdev) vblk->disk->first_minor =index_to_minor (index); vblk->disk->private_data = vblk; vblk->disk->fops = &virtblk_fops; + vblk->disk->driverfs_dev = &vdev->dev; index++;/* If barriers are supported, tell block layer that queue is ordered */
PATCH 2/4 virtio: Fix sysfs bits to have proper block symlink
In reply to Rusty RussellFrom: Jeremy Katz <[email protected]>
Fix up so that the virtio_blk devices in sysfs link correctly to their block device. This then allows them to be detected by hal, etc
--- drivers/block/virtio_blk.c | 1 + 1 file changed, 1 insertion(+)
drivers/block/virtio_blk.c +1 -0
@@ -238,6 +238,7 @@ static int virtblk_probe(struct virtio_device *vdev) vblk->disk->first_minor =index_to_minor (index); vblk->disk->private_data = vblk; vblk->disk->fops = &virtblk_fops; + vblk->disk->driverfs_dev = &vdev->dev; index++;/* If barriers are supported, tell block layer that queue is ordered */
PATCH 3/4 virtio: handle > 2 billion page balloon targets
If the host asks for a huge target towards_target() can overflow, and we up oops as we try to release more pages than we have. The simple fix is to use a 64-bit value.
--- drivers/virtio/virtio_balloon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/virtio/virtio_balloon.c +2 -2
@@ -152,7 +152,7 @@ static void virtballoon_changed(struct vwake_up (&vb->config_change); } -static inline int towards_target (struct virtio_balloon *vb) +static inline s64 towards_target (struct virtio_balloon *vb) {u32 v; __virtio_config_val(vb->vdev,
@@ -176,7 +183,7 @@ static int balloon(void *_vballoon)set_freezable ();while (!kthread_should_stop ()) { -int diff; +s64 diff;try_to_freeze (); wait_event_interruptible(vb->config_change,
PATCH 3/4 virtio: handle > 2 billion page balloon targets
In reply to Rusty RussellIf the host asks for a huge target towards_target() can overflow, and we up oops as we try to release more pages than we have. The simple fix is to use a 64-bit value.
--- drivers/virtio/virtio_balloon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/virtio/virtio_balloon.c +2 -2
@@ -152,7 +152,7 @@ static void virtballoon_changed(struct vwake_up (&vb->config_change); } -static inline int towards_target (struct virtio_balloon *vb) +static inline s64 towards_target (struct virtio_balloon *vb) {u32 v; __virtio_config_val(vb->vdev,
@@ -176,7 +183,7 @@ static int balloon(void *_vballoon)set_freezable ();while (!kthread_should_stop ()) { -int diff; +s64 diff;try_to_freeze (); wait_event_interruptible(vb->config_change,
PATCH 4/4 virtio: Enable netpoll interface for netconsole logging
From: "Amit Shah" <[email protected]>
Add a new poll_controller handler that the netpoll interface needs.
This enables netconsole logging from a kvm guest over the virtio net interface.
--- drivers/net/virtio_net.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/net/virtio_net.c +12 -0
@@ -294,6 +294,15 @@ again:return 0 ; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void virtnet_netpoll (struct net_device *dev) +{ +struct virtnet_info *vi =netdev_priv (dev); + +napi_schedule (&vi->napi); +} +#endif +static int virtnet_open (struct net_device *dev) {struct virtnet_info *vi =netdev_priv (dev);
@@ -336,6 +345,9 @@ static int virtnet_probe(struct virtio_d dev->stop = virtnet_close; dev->hard_start_xmit = start_xmit; dev->features =NETIF_F_HIGHDMA ; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = virtnet_netpoll; +#endif SET_NETDEV_DEV (dev, &vdev->dev);/* Do we support "hardware" checksums? */
PATCH 4/4 virtio: Enable netpoll interface for netconsole logging
In reply to Rusty RussellFrom: "Amit Shah" <[email protected]>
Add a new poll_controller handler that the netpoll interface needs.
This enables netconsole logging from a kvm guest over the virtio net interface.
--- drivers/net/virtio_net.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/net/virtio_net.c +12 -0
@@ -294,6 +294,15 @@ again:return 0 ; } +#ifdef CONFIG_NET_POLL_CONTROLLER +static void virtnet_netpoll (struct net_device *dev) +{ +struct virtnet_info *vi =netdev_priv (dev); + +napi_schedule (&vi->napi); +} +#endif +static int virtnet_open (struct net_device *dev) {struct virtnet_info *vi =netdev_priv (dev);
@@ -336,6 +345,9 @@ static int virtnet_probe(struct virtio_d dev->stop = virtnet_close; dev->hard_start_xmit = start_xmit; dev->features =NETIF_F_HIGHDMA ; +#ifdef CONFIG_NET_POLL_CONTROLLER + dev->poll_controller = virtnet_netpoll; +#endif SET_NETDEV_DEV (dev, &vdev->dev);/* Do we support "hardware" checksums? */