aboutsummaryrefslogtreecommitdiffstats
path: root/module/spl
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2013-09-25 14:52:29 -0700
committerBrian Behlendorf <[email protected]>2013-10-09 14:00:56 -0700
commit429fe89ceefa033120f220787265eb10d77991e7 (patch)
tree79f5a4ca63c57afbdf6711e0c7a5a1a6c498af84 /module/spl
parent6a696939617503e5c34dbb88ba62d556ce994bf1 (diff)
Consistently use local_irq_disable/local_irq_enable
It was observed that spl_kmem_cache_alloc() uses local_irq_save() and saves the interrupt state in a local variable. This would normally be fine except that spl_kmem_cache_alloc() calls spl_cache_refill() which re-enables interrupts. It is then possible that while interrupts are enabled the process is rescheduled to a different cpu before being disable again. This could result in us restoring the saved interrupt state from one cpu to another. What the consequences of this are aren't perfectly clear, but this is clearly a bug and it has the potential to cause issues. The code has been updated to just use local_irq_enable() and local_irq_disable() to avoid this. Signed-off-by: Brian Behlendorf <[email protected]>
Diffstat (limited to 'module/spl')
-rw-r--r--module/spl/spl-kmem.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/module/spl/spl-kmem.c b/module/spl/spl-kmem.c
index a2dcea039..23e47808a 100644
--- a/module/spl/spl-kmem.c
+++ b/module/spl/spl-kmem.c
@@ -1995,7 +1995,6 @@ void *
spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags)
{
spl_kmem_magazine_t *skm;
- unsigned long irq_flags;
void *obj = NULL;
SENTRY;
@@ -2003,7 +2002,7 @@ spl_kmem_cache_alloc(spl_kmem_cache_t *skc, int flags)
ASSERT(!test_bit(KMC_BIT_DESTROY, &skc->skc_flags));
ASSERT(flags & KM_SLEEP);
atomic_inc(&skc->skc_ref);
- local_irq_save(irq_flags);
+ local_irq_disable();
restart:
/* Safe to update per-cpu structure without lock, but
@@ -2025,7 +2024,7 @@ restart:
SGOTO(restart, obj = NULL);
}
- local_irq_restore(irq_flags);
+ local_irq_enable();
ASSERT(obj);
ASSERT(IS_P2ALIGNED(obj, skc->skc_obj_align));