Commit f4d53ced authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus

* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus:
  virtio: fix net driver loop case where we fail to restart
  module: fix and elaborate comments
  virtio: fix module/device unloading
  lguest: Fix uninitialized members in example launcher
parents 9bb9f222 8329d98e
...@@ -1040,6 +1040,11 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, ...@@ -1040,6 +1040,11 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
/ getpagesize(); / getpagesize();
p = get_pages(pages); p = get_pages(pages);
/* Initialize the virtqueue */
vq->next = NULL;
vq->last_avail_idx = 0;
vq->dev = dev;
/* Initialize the configuration. */ /* Initialize the configuration. */
vq->config.num = num_descs; vq->config.num = num_descs;
vq->config.irq = devices.next_irq++; vq->config.irq = devices.next_irq++;
...@@ -1057,9 +1062,6 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs, ...@@ -1057,9 +1062,6 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
for (i = &dev->vq; *i; i = &(*i)->next); for (i = &dev->vq; *i; i = &(*i)->next);
*i = vq; *i = vq;
/* Link virtqueue back to device. */
vq->dev = dev;
/* Set the routine to call when the Guest does something to this /* Set the routine to call when the Guest does something to this
* virtqueue. */ * virtqueue. */
vq->handle_output = handle_output; vq->handle_output = handle_output;
...@@ -1093,6 +1095,7 @@ static struct device *new_device(const char *name, u16 type, int fd, ...@@ -1093,6 +1095,7 @@ static struct device *new_device(const char *name, u16 type, int fd,
dev->desc = new_dev_desc(type); dev->desc = new_dev_desc(type);
dev->handle_input = handle_input; dev->handle_input = handle_input;
dev->name = name; dev->name = name;
dev->vq = NULL;
return dev; return dev;
} }
......
...@@ -223,7 +223,7 @@ static int virtblk_probe(struct virtio_device *vdev) ...@@ -223,7 +223,7 @@ static int virtblk_probe(struct virtio_device *vdev)
err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap);
if (err) { if (err) {
dev_err(&vdev->dev, "Bad/missing capacity in config\n"); dev_err(&vdev->dev, "Bad/missing capacity in config\n");
goto out_put_disk; goto out_cleanup_queue;
} }
/* If capacity is too big, truncate with warning. */ /* If capacity is too big, truncate with warning. */
...@@ -239,7 +239,7 @@ static int virtblk_probe(struct virtio_device *vdev) ...@@ -239,7 +239,7 @@ static int virtblk_probe(struct virtio_device *vdev)
blk_queue_max_segment_size(vblk->disk->queue, v); blk_queue_max_segment_size(vblk->disk->queue, v);
else if (err != -ENOENT) { else if (err != -ENOENT) {
dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); dev_err(&vdev->dev, "Bad SIZE_MAX in config\n");
goto out_put_disk; goto out_cleanup_queue;
} }
err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v);
...@@ -247,12 +247,14 @@ static int virtblk_probe(struct virtio_device *vdev) ...@@ -247,12 +247,14 @@ static int virtblk_probe(struct virtio_device *vdev)
blk_queue_max_hw_segments(vblk->disk->queue, v); blk_queue_max_hw_segments(vblk->disk->queue, v);
else if (err != -ENOENT) { else if (err != -ENOENT) {
dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); dev_err(&vdev->dev, "Bad SEG_MAX in config\n");
goto out_put_disk; goto out_cleanup_queue;
} }
add_disk(vblk->disk); add_disk(vblk->disk);
return 0; return 0;
out_cleanup_queue:
blk_cleanup_queue(vblk->disk->queue);
out_put_disk: out_put_disk:
put_disk(vblk->disk); put_disk(vblk->disk);
out_unregister_blkdev: out_unregister_blkdev:
...@@ -277,6 +279,8 @@ static void virtblk_remove(struct virtio_device *vdev) ...@@ -277,6 +279,8 @@ static void virtblk_remove(struct virtio_device *vdev)
put_disk(vblk->disk); put_disk(vblk->disk);
unregister_blkdev(major, "virtblk"); unregister_blkdev(major, "virtblk");
mempool_destroy(vblk->pool); mempool_destroy(vblk->pool);
/* There should be nothing in the queue now, so no need to shutdown */
vdev->config->del_vq(vblk->vq);
kfree(vblk); kfree(vblk);
} }
......
...@@ -247,6 +247,8 @@ static void lg_del_vq(struct virtqueue *vq) ...@@ -247,6 +247,8 @@ static void lg_del_vq(struct virtqueue *vq)
{ {
struct lguest_vq_info *lvq = vq->priv; struct lguest_vq_info *lvq = vq->priv;
/* Release the interrupt */
free_irq(lvq->config.irq, vq);
/* Tell virtio_ring.c to free the virtqueue. */ /* Tell virtio_ring.c to free the virtqueue. */
vring_del_virtqueue(vq); vring_del_virtqueue(vq);
/* Unmap the pages containing the ring. */ /* Unmap the pages containing the ring. */
......
...@@ -198,8 +198,8 @@ static int virtnet_poll(struct napi_struct *napi, int budget) ...@@ -198,8 +198,8 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
if (vi->num < vi->max / 2) if (vi->num < vi->max / 2)
try_fill_recv(vi); try_fill_recv(vi);
/* All done? */ /* Out of packets? */
if (!skb) { if (received < budget) {
netif_rx_complete(vi->dev, napi); netif_rx_complete(vi->dev, napi);
if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq)) if (unlikely(!vi->rvq->vq_ops->restart(vi->rvq))
&& netif_rx_reschedule(vi->dev, napi)) && netif_rx_reschedule(vi->dev, napi))
...@@ -404,8 +404,12 @@ static int virtnet_probe(struct virtio_device *vdev) ...@@ -404,8 +404,12 @@ static int virtnet_probe(struct virtio_device *vdev)
static void virtnet_remove(struct virtio_device *vdev) static void virtnet_remove(struct virtio_device *vdev)
{ {
unregister_netdev(vdev->priv); struct virtnet_info *vi = vdev->priv;
free_netdev(vdev->priv);
vdev->config->del_vq(vi->svq);
vdev->config->del_vq(vi->rvq);
unregister_netdev(vi->dev);
free_netdev(vi->dev);
} }
static struct virtio_device_id id_table[] = { static struct virtio_device_id id_table[] = {
......
...@@ -96,10 +96,23 @@ static int virtio_dev_probe(struct device *_d) ...@@ -96,10 +96,23 @@ static int virtio_dev_probe(struct device *_d)
return err; return err;
} }
static int virtio_dev_remove(struct device *_d)
{
struct virtio_device *dev = container_of(_d,struct virtio_device,dev);
struct virtio_driver *drv = container_of(dev->dev.driver,
struct virtio_driver, driver);
dev->config->set_status(dev, dev->config->get_status(dev)
& ~VIRTIO_CONFIG_S_DRIVER);
drv->remove(dev);
return 0;
}
int register_virtio_driver(struct virtio_driver *driver) int register_virtio_driver(struct virtio_driver *driver)
{ {
driver->driver.bus = &virtio_bus; driver->driver.bus = &virtio_bus;
driver->driver.probe = virtio_dev_probe; driver->driver.probe = virtio_dev_probe;
driver->driver.remove = virtio_dev_remove;
return driver_register(&driver->driver); return driver_register(&driver->driver);
} }
EXPORT_SYMBOL_GPL(register_virtio_driver); EXPORT_SYMBOL_GPL(register_virtio_driver);
......
...@@ -81,7 +81,8 @@ int unregister_module_notifier(struct notifier_block * nb) ...@@ -81,7 +81,8 @@ int unregister_module_notifier(struct notifier_block * nb)
} }
EXPORT_SYMBOL(unregister_module_notifier); EXPORT_SYMBOL(unregister_module_notifier);
/* We require a truly strong try_module_get() */ /* We require a truly strong try_module_get(): 0 means failure due to
ongoing or failed initialization etc. */
static inline int strong_try_module_get(struct module *mod) static inline int strong_try_module_get(struct module *mod)
{ {
if (mod && mod->state == MODULE_STATE_COMING) if (mod && mod->state == MODULE_STATE_COMING)
...@@ -952,7 +953,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs, ...@@ -952,7 +953,8 @@ static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
ret = __find_symbol(name, &owner, &crc, ret = __find_symbol(name, &owner, &crc,
!(mod->taints & TAINT_PROPRIETARY_MODULE)); !(mod->taints & TAINT_PROPRIETARY_MODULE));
if (ret) { if (ret) {
/* use_module can fail due to OOM, or module unloading */ /* use_module can fail due to OOM,
or module initialization or unloading */
if (!check_version(sechdrs, versindex, name, mod, crc) || if (!check_version(sechdrs, versindex, name, mod, crc) ||
!use_module(mod, owner)) !use_module(mod, owner))
ret = 0; ret = 0;
...@@ -1369,7 +1371,7 @@ static int verify_export_symbols(struct module *mod) ...@@ -1369,7 +1371,7 @@ static int verify_export_symbols(struct module *mod)
return ret; return ret;
} }
/* Change all symbols so that sh_value encodes the pointer directly. */ /* Change all symbols so that st_value encodes the pointer directly. */
static int simplify_symbols(Elf_Shdr *sechdrs, static int simplify_symbols(Elf_Shdr *sechdrs,
unsigned int symindex, unsigned int symindex,
const char *strtab, const char *strtab,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment