|
@@ -421,10 +421,8 @@ static void free_desc(unsigned int irq)
|
|
* The sysfs entry must be serialized against a concurrent
|
|
* The sysfs entry must be serialized against a concurrent
|
|
* irq_sysfs_init() as well.
|
|
* irq_sysfs_init() as well.
|
|
*/
|
|
*/
|
|
- mutex_lock(&sparse_irq_lock);
|
|
|
|
kobject_del(&desc->kobj);
|
|
kobject_del(&desc->kobj);
|
|
delete_irq_desc(irq);
|
|
delete_irq_desc(irq);
|
|
- mutex_unlock(&sparse_irq_lock);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* We free the descriptor, masks and stat fields via RCU. That
|
|
* We free the descriptor, masks and stat fields via RCU. That
|
|
@@ -462,20 +460,15 @@ static int alloc_descs(unsigned int start, unsigned int cnt, int node,
|
|
desc = alloc_desc(start + i, node, flags, mask, owner);
|
|
desc = alloc_desc(start + i, node, flags, mask, owner);
|
|
if (!desc)
|
|
if (!desc)
|
|
goto err;
|
|
goto err;
|
|
- mutex_lock(&sparse_irq_lock);
|
|
|
|
irq_insert_desc(start + i, desc);
|
|
irq_insert_desc(start + i, desc);
|
|
irq_sysfs_add(start + i, desc);
|
|
irq_sysfs_add(start + i, desc);
|
|
- mutex_unlock(&sparse_irq_lock);
|
|
|
|
}
|
|
}
|
|
|
|
+ bitmap_set(allocated_irqs, start, cnt);
|
|
return start;
|
|
return start;
|
|
|
|
|
|
err:
|
|
err:
|
|
for (i--; i >= 0; i--)
|
|
for (i--; i >= 0; i--)
|
|
free_desc(start + i);
|
|
free_desc(start + i);
|
|
-
|
|
|
|
- mutex_lock(&sparse_irq_lock);
|
|
|
|
- bitmap_clear(allocated_irqs, start, cnt);
|
|
|
|
- mutex_unlock(&sparse_irq_lock);
|
|
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -575,6 +568,7 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
|
|
|
|
|
|
desc->owner = owner;
|
|
desc->owner = owner;
|
|
}
|
|
}
|
|
|
|
+ bitmap_set(allocated_irqs, start, cnt);
|
|
return start;
|
|
return start;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -670,10 +664,10 @@ void irq_free_descs(unsigned int from, unsigned int cnt)
|
|
if (from >= nr_irqs || (from + cnt) > nr_irqs)
|
|
if (from >= nr_irqs || (from + cnt) > nr_irqs)
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
+ mutex_lock(&sparse_irq_lock);
|
|
for (i = 0; i < cnt; i++)
|
|
for (i = 0; i < cnt; i++)
|
|
free_desc(from + i);
|
|
free_desc(from + i);
|
|
|
|
|
|
- mutex_lock(&sparse_irq_lock);
|
|
|
|
bitmap_clear(allocated_irqs, from, cnt);
|
|
bitmap_clear(allocated_irqs, from, cnt);
|
|
mutex_unlock(&sparse_irq_lock);
|
|
mutex_unlock(&sparse_irq_lock);
|
|
}
|
|
}
|
|
@@ -720,19 +714,15 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
|
|
from, cnt, 0);
|
|
from, cnt, 0);
|
|
ret = -EEXIST;
|
|
ret = -EEXIST;
|
|
if (irq >=0 && start != irq)
|
|
if (irq >=0 && start != irq)
|
|
- goto err;
|
|
|
|
|
|
+ goto unlock;
|
|
|
|
|
|
if (start + cnt > nr_irqs) {
|
|
if (start + cnt > nr_irqs) {
|
|
ret = irq_expand_nr_irqs(start + cnt);
|
|
ret = irq_expand_nr_irqs(start + cnt);
|
|
if (ret)
|
|
if (ret)
|
|
- goto err;
|
|
|
|
|
|
+ goto unlock;
|
|
}
|
|
}
|
|
-
|
|
|
|
- bitmap_set(allocated_irqs, start, cnt);
|
|
|
|
- mutex_unlock(&sparse_irq_lock);
|
|
|
|
- return alloc_descs(start, cnt, node, affinity, owner);
|
|
|
|
-
|
|
|
|
-err:
|
|
|
|
|
|
+ ret = alloc_descs(start, cnt, node, affinity, owner);
|
|
|
|
+unlock:
|
|
mutex_unlock(&sparse_irq_lock);
|
|
mutex_unlock(&sparse_irq_lock);
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|