diff options
author | Asias He <asias@redhat.com> | 2012-05-02 22:20:51 -0400 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-05-21 22:46:12 -0400 |
commit | 90e03207f468e84258270ad07095ef50f925c17d (patch) | |
tree | b0a32e83e72f07064b9ae7156ec2bdc501734b6d /drivers | |
parent | c877bab5072c8f461397949babbac10e348ae70d (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.c | 11 |
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. */ |
7 | static unsigned int dev_index; | 8 | static DEFINE_IDA(virtio_index_ida); |
8 | 9 | ||
9 | static ssize_t device_show(struct device *_d, | 10 | static 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); |
216 | out: | ||
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); | |||
217 | void unregister_virtio_device(struct virtio_device *dev) | 223 | void 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 | } |
221 | EXPORT_SYMBOL_GPL(unregister_virtio_device); | 228 | EXPORT_SYMBOL_GPL(unregister_virtio_device); |
222 | 229 | ||