Skip to content

Commit c313a83

Browse files
author
Sebastian Andrzej Siewior
committed
percpu_ida: Use local locks
the local_irq_save() + spin_lock() does not work that well on -RT Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
1 parent 0e27e9e commit c313a83

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

lib/percpu_ida.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <linux/string.h>
2727
#include <linux/spinlock.h>
2828
#include <linux/percpu_ida.h>
29+
#include <linux/locallock.h>
30+
31+
static DEFINE_LOCAL_IRQ_LOCK(irq_off_lock);
2932

3033
struct percpu_ida_cpu {
3134
/*
@@ -148,13 +151,13 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state)
148151
unsigned long flags;
149152
int tag;
150153

151-
local_irq_save(flags);
154+
local_lock_irqsave(irq_off_lock, flags);
152155
tags = this_cpu_ptr(pool->tag_cpu);
153156

154157
/* Fastpath */
155158
tag = alloc_local_tag(tags);
156159
if (likely(tag >= 0)) {
157-
local_irq_restore(flags);
160+
local_unlock_irqrestore(irq_off_lock, flags);
158161
return tag;
159162
}
160163

@@ -173,6 +176,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state)
173176

174177
if (!tags->nr_free)
175178
alloc_global_tags(pool, tags);
179+
176180
if (!tags->nr_free)
177181
steal_tags(pool, tags);
178182

@@ -184,7 +188,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state)
184188
}
185189

186190
spin_unlock(&pool->lock);
187-
local_irq_restore(flags);
191+
local_unlock_irqrestore(irq_off_lock, flags);
188192

189193
if (tag >= 0 || state == TASK_RUNNING)
190194
break;
@@ -196,7 +200,7 @@ int percpu_ida_alloc(struct percpu_ida *pool, int state)
196200

197201
schedule();
198202

199-
local_irq_save(flags);
203+
local_lock_irqsave(irq_off_lock, flags);
200204
tags = this_cpu_ptr(pool->tag_cpu);
201205
}
202206
if (state != TASK_RUNNING)
@@ -221,7 +225,7 @@ void percpu_ida_free(struct percpu_ida *pool, unsigned tag)
221225

222226
BUG_ON(tag >= pool->nr_tags);
223227

224-
local_irq_save(flags);
228+
local_lock_irqsave(irq_off_lock, flags);
225229
tags = this_cpu_ptr(pool->tag_cpu);
226230

227231
spin_lock(&tags->lock);
@@ -253,7 +257,7 @@ void percpu_ida_free(struct percpu_ida *pool, unsigned tag)
253257
spin_unlock(&pool->lock);
254258
}
255259

256-
local_irq_restore(flags);
260+
local_unlock_irqrestore(irq_off_lock, flags);
257261
}
258262
EXPORT_SYMBOL_GPL(percpu_ida_free);
259263

@@ -345,7 +349,7 @@ int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn,
345349
struct percpu_ida_cpu *remote;
346350
unsigned cpu, i, err = 0;
347351

348-
local_irq_save(flags);
352+
local_lock_irqsave(irq_off_lock, flags);
349353
for_each_possible_cpu(cpu) {
350354
remote = per_cpu_ptr(pool->tag_cpu, cpu);
351355
spin_lock(&remote->lock);
@@ -367,7 +371,7 @@ int percpu_ida_for_each_free(struct percpu_ida *pool, percpu_ida_cb fn,
367371
}
368372
spin_unlock(&pool->lock);
369373
out:
370-
local_irq_restore(flags);
374+
local_unlock_irqrestore(irq_off_lock, flags);
371375
return err;
372376
}
373377
EXPORT_SYMBOL_GPL(percpu_ida_for_each_free);

0 commit comments

Comments
 (0)