Skip to content

Commit

Permalink
Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/rusty/linux

Pull virtio updates from Rusty Russell:
 "One cc: stable commit, the rest are a series of minor cleanups which
  have been sitting in MST's tree during my vacation.  I changed a
  function name and made one trivial change, then they spent two days in
  linux-next"

* tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: (25 commits)
  virtio-rng: refactor probe error handling
  virtio_scsi: drop scan callback
  virtio_balloon: enable VQs early on restore
  virtio_scsi: fix race on device removal
  virito_scsi: use freezable WQ for events
  virtio_net: enable VQs early on restore
  virtio_console: enable VQs early on restore
  virtio_scsi: enable VQs early on restore
  virtio_blk: enable VQs early on restore
  virtio_scsi: move kick event out from virtscsi_init
  virtio_net: fix use after free on allocation failure
  9p/trans_virtio: enable VQs early
  virtio_console: enable VQs early
  virtio_blk: enable VQs early
  virtio_net: enable VQs early
  virtio: add API to enable VQs early
  virtio_net: minor cleanup
  virtio-net: drop config_mutex
  virtio_net: drop config_enable
  virtio-blk: drop config_mutex
  ...
  • Loading branch information
torvalds committed Oct 18, 2014
2 parents 50edb5c + 1bbc260 commit 0e6e58f
Show file tree
Hide file tree
Showing 15 changed files with 207 additions and 137 deletions.
40 changes: 11 additions & 29 deletions drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,6 @@ struct virtio_blk
/* Process context for config space updates */
struct work_struct config_work;

/* Lock for config space updates */
struct mutex config_lock;

/* enable config space updates */
bool config_enable;

/* What host tells us, plus 2 for header & tailer. */
unsigned int sg_elems;

Expand Down Expand Up @@ -347,10 +341,6 @@ static void virtblk_config_changed_work(struct work_struct *work)
char *envp[] = { "RESIZE=1", NULL };
u64 capacity, size;

mutex_lock(&vblk->config_lock);
if (!vblk->config_enable)
goto done;

/* Host must always specify the capacity. */
virtio_cread(vdev, struct virtio_blk_config, capacity, &capacity);

Expand All @@ -374,8 +364,6 @@ static void virtblk_config_changed_work(struct work_struct *work)
set_capacity(vblk->disk, capacity);
revalidate_disk(vblk->disk);
kobject_uevent_env(&disk_to_dev(vblk->disk)->kobj, KOBJ_CHANGE, envp);
done:
mutex_unlock(&vblk->config_lock);
}

static void virtblk_config_changed(struct virtio_device *vdev)
Expand Down Expand Up @@ -606,10 +594,8 @@ static int virtblk_probe(struct virtio_device *vdev)

vblk->vdev = vdev;
vblk->sg_elems = sg_elems;
mutex_init(&vblk->config_lock);

INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
vblk->config_enable = true;

err = init_vq(vblk);
if (err)
Expand Down Expand Up @@ -733,6 +719,8 @@ static int virtblk_probe(struct virtio_device *vdev)
if (!err && opt_io_size)
blk_queue_io_opt(q, blk_size * opt_io_size);

virtio_device_ready(vdev);

add_disk(vblk->disk);
err = device_create_file(disk_to_dev(vblk->disk), &dev_attr_serial);
if (err)
Expand Down Expand Up @@ -771,10 +759,8 @@ static void virtblk_remove(struct virtio_device *vdev)
int index = vblk->index;
int refc;

/* Prevent config work handler from accessing the device. */
mutex_lock(&vblk->config_lock);
vblk->config_enable = false;
mutex_unlock(&vblk->config_lock);
/* Make sure no work handler is accessing the device. */
flush_work(&vblk->config_work);

del_gendisk(vblk->disk);
blk_cleanup_queue(vblk->disk->queue);
Expand All @@ -784,8 +770,6 @@ static void virtblk_remove(struct virtio_device *vdev)
/* Stop all the virtqueues. */
vdev->config->reset(vdev);

flush_work(&vblk->config_work);

refc = atomic_read(&disk_to_dev(vblk->disk)->kobj.kref.refcount);
put_disk(vblk->disk);
vdev->config->del_vqs(vdev);
Expand All @@ -805,11 +789,7 @@ static int virtblk_freeze(struct virtio_device *vdev)
/* Ensure we don't receive any more interrupts */
vdev->config->reset(vdev);

/* Prevent config work handler from accessing the device. */
mutex_lock(&vblk->config_lock);
vblk->config_enable = false;
mutex_unlock(&vblk->config_lock);

/* Make sure no work handler is accessing the device. */
flush_work(&vblk->config_work);

blk_mq_stop_hw_queues(vblk->disk->queue);
Expand All @@ -823,12 +803,14 @@ static int virtblk_restore(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv;
int ret;

vblk->config_enable = true;
ret = init_vq(vdev->priv);
if (!ret)
blk_mq_start_stopped_hw_queues(vblk->disk->queue, true);
if (ret)
return ret;

return ret;
virtio_device_ready(vdev);

blk_mq_start_stopped_hw_queues(vblk->disk->queue, true);
return 0;
}
#endif

Expand Down
15 changes: 9 additions & 6 deletions drivers/char/hw_random/virtio-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ static int probe_common(struct virtio_device *vdev)

vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL);
if (index < 0) {
kfree(vi);
return index;
err = index;
goto err_ida;
}
sprintf(vi->name, "virtio_rng.%d", index);
init_completion(&vi->have_data);
Expand All @@ -128,13 +128,16 @@ static int probe_common(struct virtio_device *vdev)
vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
if (IS_ERR(vi->vq)) {
err = PTR_ERR(vi->vq);
vi->vq = NULL;
kfree(vi);
ida_simple_remove(&rng_index_ida, index);
return err;
goto err_find;
}

return 0;

err_find:
ida_simple_remove(&rng_index_ida, index);
err_ida:
kfree(vi);
return err;
}

static void remove_common(struct virtio_device *vdev)
Expand Down
4 changes: 4 additions & 0 deletions drivers/char/virtio_console.c
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,8 @@ static int add_port(struct ports_device *portdev, u32 id)
spin_lock_init(&port->outvq_lock);
init_waitqueue_head(&port->waitqueue);

virtio_device_ready(portdev->vdev);

/* Fill the in_vq with buffers so the host can send us data. */
nr_added_bufs = fill_queue(port->in_vq, &port->inbuf_lock);
if (!nr_added_bufs) {
Expand Down Expand Up @@ -2182,6 +2184,8 @@ static int virtcons_restore(struct virtio_device *vdev)
if (ret)
return ret;

virtio_device_ready(portdev->vdev);

if (use_multiport(portdev))
fill_queue(portdev->c_ivq, &portdev->c_ivq_lock);

Expand Down
6 changes: 1 addition & 5 deletions drivers/misc/mic/card/mic_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,16 +462,12 @@ static void mic_handle_config_change(struct mic_device_desc __iomem *d,
struct mic_device_ctrl __iomem *dc
= (void __iomem *)d + mic_aligned_desc_size(d);
struct mic_vdev *mvdev = (struct mic_vdev *)ioread64(&dc->vdev);
struct virtio_driver *drv;

if (ioread8(&dc->config_change) != MIC_VIRTIO_PARAM_CONFIG_CHANGED)
return;

dev_dbg(mdrv->dev, "%s %d\n", __func__, __LINE__);
drv = container_of(mvdev->vdev.dev.driver,
struct virtio_driver, driver);
if (drv->config_changed)
drv->config_changed(&mvdev->vdev);
virtio_config_changed(&mvdev->vdev);
iowrite8(1, &dc->guest_ack);
}

Expand Down
44 changes: 12 additions & 32 deletions drivers/net/virtio_net.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,6 @@ struct virtnet_info {
/* Host can handle any s/g split between our header and packet data */
bool any_header_sg;

/* enable config space updates */
bool config_enable;

/* Active statistics */
struct virtnet_stats __percpu *stats;

Expand All @@ -135,9 +132,6 @@ struct virtnet_info {
/* Work struct for config space updates */
struct work_struct config_work;

/* Lock for config space updates */
struct mutex config_lock;

/* Does the affinity hint is set for virtqueues? */
bool affinity_hint_set;

Expand Down Expand Up @@ -1414,13 +1408,9 @@ static void virtnet_config_changed_work(struct work_struct *work)
container_of(work, struct virtnet_info, config_work);
u16 v;

mutex_lock(&vi->config_lock);
if (!vi->config_enable)
goto done;

if (virtio_cread_feature(vi->vdev, VIRTIO_NET_F_STATUS,
struct virtio_net_config, status, &v) < 0)
goto done;
return;

if (v & VIRTIO_NET_S_ANNOUNCE) {
netdev_notify_peers(vi->dev);
Expand All @@ -1431,7 +1421,7 @@ static void virtnet_config_changed_work(struct work_struct *work)
v &= VIRTIO_NET_S_LINK_UP;

if (vi->status == v)
goto done;
return;

vi->status = v;

Expand All @@ -1442,8 +1432,6 @@ static void virtnet_config_changed_work(struct work_struct *work)
netif_carrier_off(vi->dev);
netif_tx_stop_all_queues(vi->dev);
}
done:
mutex_unlock(&vi->config_lock);
}

static void virtnet_config_changed(struct virtio_device *vdev)
Expand Down Expand Up @@ -1764,8 +1752,6 @@ static int virtnet_probe(struct virtio_device *vdev)
u64_stats_init(&virtnet_stats->rx_syncp);
}

mutex_init(&vi->config_lock);
vi->config_enable = true;
INIT_WORK(&vi->config_work, virtnet_config_changed_work);

/* If we can receive ANY GSO packets, we must allocate large ones. */
Expand Down Expand Up @@ -1813,6 +1799,8 @@ static int virtnet_probe(struct virtio_device *vdev)
goto free_vqs;
}

virtio_device_ready(vdev);

/* Last of all, set up some receive buffers. */
for (i = 0; i < vi->curr_queue_pairs; i++) {
try_fill_recv(&vi->rq[i], GFP_KERNEL);
Expand Down Expand Up @@ -1849,6 +1837,8 @@ static int virtnet_probe(struct virtio_device *vdev)
return 0;

free_recv_bufs:
vi->vdev->config->reset(vdev);

free_receive_bufs(vi);
unregister_netdev(dev);
free_vqs:
Expand Down Expand Up @@ -1882,17 +1872,13 @@ static void virtnet_remove(struct virtio_device *vdev)

unregister_hotcpu_notifier(&vi->nb);

/* Prevent config work handler from accessing the device. */
mutex_lock(&vi->config_lock);
vi->config_enable = false;
mutex_unlock(&vi->config_lock);
/* Make sure no work handler is accessing the device. */
flush_work(&vi->config_work);

unregister_netdev(vi->dev);

remove_vq_common(vi);

flush_work(&vi->config_work);

free_percpu(vi->stats);
free_netdev(vi->dev);
}
Expand All @@ -1905,10 +1891,8 @@ static int virtnet_freeze(struct virtio_device *vdev)

unregister_hotcpu_notifier(&vi->nb);

/* Prevent config work handler from accessing the device */
mutex_lock(&vi->config_lock);
vi->config_enable = false;
mutex_unlock(&vi->config_lock);
/* Make sure no work handler is accessing the device */
flush_work(&vi->config_work);

netif_device_detach(vi->dev);
cancel_delayed_work_sync(&vi->refill);
Expand All @@ -1923,8 +1907,6 @@ static int virtnet_freeze(struct virtio_device *vdev)

remove_vq_common(vi);

flush_work(&vi->config_work);

return 0;
}

Expand All @@ -1937,6 +1919,8 @@ static int virtnet_restore(struct virtio_device *vdev)
if (err)
return err;

virtio_device_ready(vdev);

if (netif_running(vi->dev)) {
for (i = 0; i < vi->curr_queue_pairs; i++)
if (!try_fill_recv(&vi->rq[i], GFP_KERNEL))
Expand All @@ -1948,10 +1932,6 @@ static int virtnet_restore(struct virtio_device *vdev)

netif_device_attach(vi->dev);

mutex_lock(&vi->config_lock);
vi->config_enable = true;
mutex_unlock(&vi->config_lock);

rtnl_lock();
virtnet_set_queues(vi, vi->curr_queue_pairs);
rtnl_unlock();
Expand Down
9 changes: 1 addition & 8 deletions drivers/s390/kvm/kvm_virtio.c
Original file line number Diff line number Diff line change
Expand Up @@ -406,15 +406,8 @@ static void kvm_extint_handler(struct ext_code ext_code,

switch (param) {
case VIRTIO_PARAM_CONFIG_CHANGED:
{
struct virtio_driver *drv;
drv = container_of(vq->vdev->dev.driver,
struct virtio_driver, driver);
if (drv->config_changed)
drv->config_changed(vq->vdev);

virtio_config_changed(vq->vdev);
break;
}
case VIRTIO_PARAM_DEV_ADD:
schedule_work(&hotplug_work);
break;
Expand Down
6 changes: 1 addition & 5 deletions drivers/s390/kvm/virtio_ccw.c
Original file line number Diff line number Diff line change
Expand Up @@ -940,11 +940,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
vring_interrupt(0, vq);
}
if (test_bit(0, &vcdev->indicators2)) {
drv = container_of(vcdev->vdev.dev.driver,
struct virtio_driver, driver);

if (drv && drv->config_changed)
drv->config_changed(&vcdev->vdev);
virtio_config_changed(&vcdev->vdev);
clear_bit(0, &vcdev->indicators2);
}
}
Expand Down
Loading

0 comments on commit 0e6e58f

Please sign in to comment.