diff options
author | Stanislaw Gruszka <stf_xl@wp.pl> | 2005-11-30 01:16:41 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2005-11-30 01:16:41 +0100 |
commit | 64bf69ddff7637b7ed7acf9b2a823cc0ee519439 (patch) | |
tree | fb3a746e36bcfa307979bef2a20ce5f1d32ec537 /net/atm/resources.c | |
parent | [ATM]: avoid race conditions related to atm_devs list (diff) | |
download | linux-64bf69ddff7637b7ed7acf9b2a823cc0ee519439.tar.xz linux-64bf69ddff7637b7ed7acf9b2a823cc0ee519439.zip |
[ATM]: deregistration removes device from atm_devs list immediately
atm_dev_deregister() removes device from atm_dev list immediately to
prevent operations on a phantom device. Decision to free device based
only on ->refcnt now. Remove shutdown_atm_dev() use atm_dev_deregister()
instead. atm_dev_deregister() also asynchronously releases all vccs
related to device.
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/atm/resources.c')
-rw-r--r-- | net/atm/resources.c | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/net/atm/resources.c b/net/atm/resources.c index ad533b02b84f..c8c459fcb038 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -70,6 +70,7 @@ struct atm_dev *atm_dev_lookup(int number) return dev; } + struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, int number, unsigned long *flags) { @@ -123,37 +124,22 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, void atm_dev_deregister(struct atm_dev *dev) { - unsigned long warning_time; - - atm_proc_dev_deregister(dev); - + BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags)); + set_bit(ATM_DF_REMOVED, &dev->flags); + + /* + * if we remove current device from atm_devs list, new device + * with same number can appear, such we need deregister proc, + * release async all vccs and remove them from vccs list too + */ down(&atm_dev_mutex); list_del(&dev->dev_list); up(&atm_dev_mutex); - warning_time = jiffies; - while (atomic_read(&dev->refcnt) != 1) { - msleep(250); - if ((jiffies - warning_time) > 10 * HZ) { - printk(KERN_EMERG "atm_dev_deregister: waiting for " - "dev %d to become free. Usage count = %d\n", - dev->number, atomic_read(&dev->refcnt)); - warning_time = jiffies; - } - } - - kfree(dev); -} + atm_dev_release_vccs(dev); + atm_proc_dev_deregister(dev); -void shutdown_atm_dev(struct atm_dev *dev) -{ - if (atomic_read(&dev->refcnt) > 1) { - set_bit(ATM_DF_CLOSE, &dev->flags); - return; - } - if (dev->ops->dev_close) - dev->ops->dev_close(dev); - atm_dev_deregister(dev); + atm_dev_put(dev); } @@ -433,4 +419,3 @@ void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos) EXPORT_SYMBOL(atm_dev_register); EXPORT_SYMBOL(atm_dev_deregister); EXPORT_SYMBOL(atm_dev_lookup); -EXPORT_SYMBOL(shutdown_atm_dev); |