aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAsias He <asias@redhat.com>2012-05-02 22:20:51 -0400
committerRusty Russell <rusty@rustcorp.com.au>2012-05-21 22:46:12 -0400
commit90e03207f468e84258270ad07095ef50f925c17d (patch)
treeb0a32e83e72f07064b9ae7156ec2bdc501734b6d /drivers
parentc877bab5072c8f461397949babbac10e348ae70d (diff)
virtio: Use ida to allocate virtio index
Current index allocation in virtio is based on a monotonically increasing variable "index". This means we'll run out of numbers after a while. E.g. someone crazy doing this in host side. while(1) { hot-plug a virtio device hot-unplug the virito devcie } Signed-off-by: Asias He <asias@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/virtio/virtio.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 984c501c258f..f3558070e375 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -2,9 +2,10 @@
2#include <linux/spinlock.h> 2#include <linux/spinlock.h>
3#include <linux/virtio_config.h> 3#include <linux/virtio_config.h>
4#include <linux/module.h> 4#include <linux/module.h>
5#include <linux/idr.h>
5 6
6/* Unique numbering for virtio devices. */ 7/* Unique numbering for virtio devices. */
7static unsigned int dev_index; 8static DEFINE_IDA(virtio_index_ida);
8 9
9static ssize_t device_show(struct device *_d, 10static ssize_t device_show(struct device *_d,
10 struct device_attribute *attr, char *buf) 11 struct device_attribute *attr, char *buf)
@@ -193,7 +194,11 @@ int register_virtio_device(struct virtio_device *dev)
193 dev->dev.bus = &virtio_bus; 194 dev->dev.bus = &virtio_bus;
194 195
195 /* Assign a unique device index and hence name. */ 196 /* Assign a unique device index and hence name. */
196 dev->index = dev_index++; 197 err = ida_simple_get(&virtio_index_ida, 0, 0, GFP_KERNEL);
198 if (err < 0)
199 goto out;
200
201 dev->index = err;
197 dev_set_name(&dev->dev, "virtio%u", dev->index); 202 dev_set_name(&dev->dev, "virtio%u", dev->index);
198 203
199 /* We always start by resetting the device, in case a previous 204 /* We always start by resetting the device, in case a previous
@@ -208,6 +213,7 @@ int register_virtio_device(struct virtio_device *dev)
208 /* device_register() causes the bus infrastructure to look for a 213 /* device_register() causes the bus infrastructure to look for a
209 * matching driver. */ 214 * matching driver. */
210 err = device_register(&dev->dev); 215 err = device_register(&dev->dev);
216out:
211 if (err) 217 if (err)
212 add_status(dev, VIRTIO_CONFIG_S_FAILED); 218 add_status(dev, VIRTIO_CONFIG_S_FAILED);
213 return err; 219 return err;
@@ -217,6 +223,7 @@ EXPORT_SYMBOL_GPL(register_virtio_device);
217void unregister_virtio_device(struct virtio_device *dev) 223void unregister_virtio_device(struct virtio_device *dev)
218{ 224{
219 device_unregister(&dev->dev); 225 device_unregister(&dev->dev);
226 ida_simple_remove(&virtio_index_ida, dev->index);
220} 227}
221EXPORT_SYMBOL_GPL(unregister_virtio_device); 228EXPORT_SYMBOL_GPL(unregister_virtio_device);
222 229